0

Моя проблема: я получаю CoreData Серьезная ошибка, но я не знаю почему. Ошибка аналогична:Ошибка CoreData при использовании 2 NSFetchedResultsController в той же таблице

Core Data Serious Application Error at controllerDidChangeContent

У меня есть контроллер, отображающий список пользователей (хранится в таблице пользователей в CoreData). Очень прямо.

Во втором диспетчере просмотра я получаю список пользователей с сервера, а также получаю файлы, хранящиеся в CoreData, чтобы видеть, если у нас уже есть один и тот же пользователь локально (в этом случае я меняю цвет фона ячейки), и я также добавляю заголовок с заголовком в первой ячейке первого раздела.

Вот как я инициализировать мой fetchController в 1-ом ViewController инициализации конструктора:

let modelMethodNameForSection = "firstCharOfFirstname" 
let requestHelper = NSFetchRequest(entityName: modelEntityClass) 
requestHelper.predicate = NSPredicate(format: "friend.groupA == YES") 
requestHelper.sortDescriptors = [sortDescriptor] 

let managedObjectCtx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext 

fetchedResultsController = NSFetchedResultsController(fetchRequest: requestHelper, managedObjectContext: managedObjectCtx, sectionNameKeyPath: modelMethodNameForSection, cacheName: nil) 

Вот делегаты:

//MARK: - NSFetchedResultsControllerDelegate 
    func controllerWillChangeContent(controller: NSFetchedResultsController) 
    { 
    tableView!.beginUpdates() 
    } 

    func controllerDidChangeContent(controller: NSFetchedResultsController) 
    { 
    tableView!.endUpdates() 
    if let fetchedObjects = controller.fetchedObjects { 
     segmentedControlDelegate?.updateSegment(fetchedObjects.count, listType: ProfilePeopleListType.Friends) //listType doesn t matter here 
    } 
    } 

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) 
    { 
    switch (type) { 
    case .Insert: 
     if let indexPath = newIndexPath { 
     tableView!.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 
     break 
    case .Delete: 
     if let indexPath = indexPath { 
     tableView!.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 
     break 
    case .Update: 
     if let indexPath = indexPath { 
     if let cell = tableView!.cellForRowAtIndexPath(indexPath) as? UserViewCell { //We need to check that it's a UserViewCell, because it can be another class 
      configureCell(cell, atIndexPath: indexPath) 
     } 
     } 
     break 
    case .Move: 
     if let indexPath = indexPath { 
     tableView!.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade) 
     } 

     if let newIndexPath = newIndexPath { 
     tableView!.insertRowsAtIndexPaths([newIndexPath], withRowAnimation: .Fade) 
     } 
     break 
    } 
    } 

    func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) 
    { 
    switch type { 
    case .Insert: 
     tableView!.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
    case .Delete: 
     tableView!.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) 
    default: 
     return 
    } 
    } 

Вот код для 2-го ViewController отображение результатов слилась с сервер:

let modelMethodNameForSection = "firstCharOfFirstname" 
let requestHelper = NSFetchRequest(entityName: modelEntityClass) 
requestHelper.predicate = NSPredicate(format: "friend.groupA == YES") 
requestHelper.sortDescriptors = [sortDescriptor] 

let managedObjectCtx = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext 

fetchedResultsController = NSFetchedResultsController(fetchRequest: requestHelper, managedObjectContext: managedObjectCtx, sectionNameKeyPath: modelMethodNameForSection, cacheName: nil) 

My TableView отображает заголовок, содержащий заголовок в строках [0] из секций [0] (верхняя часть таблицы)

//MARK: - NSFetchedResultsControllerDelegate 
    //When the local database Friends table changes we are notified 
    func controllerWillChangeContent(controller: NSFetchedResultsController) 
    { 

    } 

    func controllerDidChangeContent(controller: NSFetchedResultsController) 
    { 

    } 

    func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) 
    { 

    //We refresh the lists with new data from local Database 
    let listFriendsFilterBlock = peopleListWithOwnerFriendsFilter() 
    tableView?.reloadData() 
    } 

    func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) 
    { 
    //We don't have any sections in the users list merged with server data 

    } 

EDIT журнал Крушения:

[;2016-03-16 18:51:10.511 *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.29.5/UITableView.m:1720 2016-03-16 18:51:10.511 CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

+0

сообщите нам серьезное сообщение об ошибке, которое вы получите – Wain

+0

вот оно, проблема с номерами строк. – Mikael

+0

Я действительно не понимаю, как может возникнуть исключение, зная, что NSFetchedResultsController даже не знает о tableView (мы даже не указали на него в коде) – Mikael

ответ

0

Из сообщения об ошибке вашего FRC сообщает вам (делегату), что что-то изменилось, в результате этого вы обновляете данные данных источника данных, но вы неправильно рассказываете табличному представлению о вставках/удалениях.

В этом конкретном случае вставлен 1 элемент, и в табличном представлении не было указано никаких вставок.

Это возможно, хотя это трудно сказать, связанные с:

//We refresh the lists with new data from local Database 
let listFriendsFilterBlock = peopleListWithOwnerFriendsFilter() 
tableView?.reloadData() 

потому, что такой подход к освежающим таблица должна быть реализована в controllerDidChangeContent не didChangeObject. Вы должны знать, что изменение завершено до перезагрузки.

+0

Я переместил свой код в контроллереDidChangeContent, но у меня все еще есть проблема , Одна из проблем заключается в том, что у меня нет способа узнать, какой столбец вызывает проблему. Все, что я знаю, это то, что макет tableView с корпусом коммутатора сломается при ошибке. Подобно верхней вставке контента tableview, становится действительно огромным пробелом. Вторая проблема заключается в том, что я бы не хотел говорить о вставке/удалении на этом втором контроллере представления, поскольку я отображаю данные, смешанные между сервером и клиентом ... Я предпочитаю просто обновлять весь список на данный момент. Почему ссылка между coredata на nd tableview, хотя – Mikael

+0

Является ли второе обновление таблицы действительно управляемым FRC? Я не уверен, почему вы не знаете, что нужно обновлять, поскольку они находятся в разных контроллерах. – Wain

+0

Второй tableView просто использует источник данных, который является слиянием между FRC fetchedObjects и данными сервера. Когда coredata имеет изменения, я запрашиваю сервер и полностью загружаю таблицу. Может быть, я тоже должен опорожнить его перед руками? – Mikael

Смежные вопросы