2016-12-07 15 views
0

内の行を挿入するとき、私はfetchedResultsControllerデリゲートを使用して、新しいエンティティが作成されたときに私のtableViewを更新するには、次の方法を使用しています:これは動作します
クラッシュ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を使用していますr。私はいくつかの研究を行い、答えはnumberOfRowsInSectionを更新すると主張していますが、セクションの行数はfetchedResultControllerセクションのオブジェクト数に設定されています。私はinsertionRowsの前に&の後に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で述べたように、問題を解決するためにしなければならなかったものです。

あなたがコンテンツを更新し始めたことにtableViewを知らせるために忘れてい
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    self.tableView.beginUpdates() 
} 

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

答えて

1

[self.tableView beginUpdates]; 

[self.tableView endUpdates]; 

修正セクションと行の数がフェッチと一致する必要がもの。 https://developer.apple.com/reference/coredata/nsfetchedresultscontrollerdelegate

+0

ありがとう:

がドキュメントに見て、同様の例があります!ソリューションを示すために私の答えを更新しました。私は過去3時間頭を頭から引き離していた。 –

+0

また、これらのメソッドをNSFetchedResultsControllerデリゲートメソッド(controllerWillChangeContent&controllerDidChangeContent)内にスローする必要があることにも言及してください。私はbeginUpdatesとendUpdatesを(それぞれ)self.tableView.insertRowsの前後に配置しようとしましたが、解決策ではありませんでした。 –

+0

はい、これが私がドキュメントへのリンクを提供した理由です。それがどのように動作し、ソースからどのように使用するかを知ることは良いことです。 – zepar

関連する問題