2016-12-07 67 views
0

插入時行我使用下面的方法新的實體創建時更新我的​​tableView,使用fetchedResultsController委託:
崩潰在fetchedResultsController委託方法(IOS)

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch type { 
    case .insert: 
     //Crash here 
     self.tableView.insertRows(at: [newIndexPath!], with: .automatic) 
    default: 
     print("default") 
    } 
} 

這工作,但有時我得到以下崩潰:

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. 

The number of rows contained in an existing section after the update (6) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). *** First throw call stack:

林正在使用fetchedResultsControlle河我做了一些研究,答案聲稱更新numberOfRowsInSection,但是我將該節中的行數設置爲fetchedResultController部分中的對象數。我在插入行之前嘗試在&之後調用reloadData(),但這不能解決它。這裏是我的numberOfRowsInSection方法:

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    if let sections = fetchedResultsController.sections { 
     let currentSection = sections[section] 
     return currentSection.numberOfObjects 
    } 
    return 0 
} 

而且我fetchedResultsController:

lazy var fetchedResultsController: NSFetchedResultsController<Project> = { 

    let userFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Project") 
    let coreDataStack = CoreDataStack.default() 
    let managedContext = coreDataStack?.managedObjectContext 

    let primarySortDescriptor = NSSortDescriptor(key: "dateCreated", ascending: false) 
    userFetchRequest.sortDescriptors = [primarySortDescriptor] 

     let frc = NSFetchedResultsController(
     fetchRequest: userFetchRequest, 
     managedObjectContext: managedContext!, 
     sectionNameKeyPath: nil, 
     cacheName: nil) 

    frc.delegate = self 

    return frc as! NSFetchedResultsController<Project> 
}() 

// SOLUTION:
這是我必須做的,以解決這個問題,通過Zepar提及。

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    self.tableView.beginUpdates() 
} 

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    self.tableView.endUpdates() 
} 

回答

1

你都忘了告知的tableView的內容開始更新:

[self.tableView beginUpdates]; 

[self.tableView endUpdates]; 

修改部分和行數必須與所取得的一致那些。

。看看文檔,有一個例子,以及: https://developer.apple.com/reference/coredata/nsfetchedresultscontrollerdelegate

+0

THANK YOU!我已經更新了我的答案以顯示解決方案。在過去的3個小時裏,我把頭髮拉出頭頂。 –

+0

您還應該提到應該將這些方法放在NSFetchedResultsController委託方法(controllerWillChangeContent&controllerDidChangeContent)中。我嘗試了在begin()和endUpdates之前和之後(分別)self.tableView.insertRows,而不是解決方案。 –

+0

是的,這就是爲什麼,我提供了鏈接到文檔。很高興知道它是如何工作的以及如何使用源代碼。 – zepar