2017-02-13 14 views
1

私はこのエラーとスタック:削除を呼び出すのは誰ですか?

CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. attempt to delete row 0 from section 0, but there are only 0 sections before the update with userInfo (null)

は私が削除操作を呼び出す見当がつかない - 正直なところ、私はちょうどプロジェクト全体で任意の削除を持っていない話します。どのようにそのようなケースをデバッグするためのアイデア?

public func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch(type) { 
    case .insert: 
     self.operation.append(BlockOperation(block: { 
                 self.tableView?.insertRows(at: [newIndexPath!], with: .bottom) 
                }) 
     ) 
     // self.tableView?.scrollToRow(at: newIndexPath, at: .bottom, animated: true) 
     break 
    case .update: 
     self.operation.append(BlockOperation(block: { 
                 self.tableView?.reloadRows(at: [indexPath!], with: .bottom) 
                }) 
     ) 
     break 
    default: 
     break 
    } 
} 

public func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    self.tableView?.beginUpdates() 
    for o in self.operation { 
     o.start() 
    } 
    self.tableView?.endUpdates() 

} 

ありがとうございます。

アップデート1

override public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell: ChannelTableCell = tableView.dequeueReusableCell(withIdentifier: "ChannelTableCell", for: indexPath) as! ChannelTableCell 
    cell.setChannel(self.channelController.object(at: indexPath), delegate: self) 

    return cell 
} 

アップデート2

私はdidChange方法を簡素化し、今reloadRows()の呼び出しでエラーを取得しています。

public func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch(type) { 
    case .insert: 
     self.tableView?.insertRows(at: [newIndexPath!], with: .bottom) 
     break; 
    case .update: 
     self.tableView?.reloadRows(at: [indexPath!], with: .bottom) 
     break 
    default: 
     break 
    } 
} 

スタック

*** First throw call stack: 
(
    0 CoreFoundation      0x0000000109db2d4b __exceptionPreprocess + 171 
    1 libobjc.A.dylib      0x00000001089cb21e objc_exception_throw + 48 
    2 CoreFoundation      0x0000000109db6e42 +[NSException raise:format:arguments:] + 98 
    3 Foundation       0x000000010856066d -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 195 
    4 UIKit        0x000000010ab1ab60 -[UITableView _endCellAnimationsWithContext:] + 6265 
    5 UIKit        0x000000010ab34f62 -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] + 331 
    6 Joker        0x00000001080335ac _TFC5Joker17AirViewController10controllerfTGCSo26NSFetchedResultsControllerPSo20NSFetchRequestResult__9didChangeP_2atGSqV10Foundation9IndexPath_3forOSC26NSFetchedResultsChangeType12newIndexPathGSqS4___T_ + 860 
    7 Joker        0x0000000108033740 _TToFC5Joker17AirViewController10controllerfTGCSo26NSFetchedResultsControllerPSo20NSFetchRequestResult__9didChangeP_2atGSqV10Foundation9IndexPath_3forOSC26NSFetchedResultsChangeType12newIndexPathGSqS4___T_ + 256 
    8 CoreData       0x0000000109a25400 __82-[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:]_block_invoke + 6608 
    9 CoreData       0x00000001098fa9a7 developerSubmittedBlockToNSManagedObjectContextPerform + 199 
    10 CoreData       0x00000001098fa85f -[NSManagedObjectContext performBlockAndWait:] + 255 
    11 CoreData       0x0000000109a23a17 -[NSFetchedResultsController(PrivateMethods) _core_managedObjectContextDidChange:] + 119 
    12 CoreFoundation      0x0000000109d505ec __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12 
    13 CoreFoundation      0x0000000109d504eb _CFXRegistrationPost + 427 
    14 CoreFoundation      0x0000000109d50252 ___CFXNotificationPost_block_invoke + 50 
    15 CoreFoundation      0x0000000109d13282 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 2018 
    16 CoreFoundation      0x0000000109d1231b _CFXNotificationPost + 667 
    17 Foundation       0x000000010849181b -[NSNotificationCenter postNotificationName:object:userInfo:] + 66 
    18 CoreData       0x00000001098e2d90 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 704 
    19 CoreData       0x0000000109979a91 -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:deletions:updates:refreshes:deferrals:wasMerge:] + 1713 
    20 CoreData       0x00000001098dcb32 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 3554 
    21 CoreData       0x00000001098b5764 -[NSManagedObjectContext executeFetchRequest:error:] + 420 
    22 libswiftCoreData.dylib    0x000000010c769e78 _TFE8CoreDataCSo22NSManagedObjectContext5fetchuRxSo20NSFetchRequestResultrfzGCSo14NSFetchRequestx_GSax_ + 56 
    ... 
) 
+0

関連していません:テーブルビューでブロック操作を使用する利点は何ですか? – vadian

+0

CoreDataに関連していません。間違った挿入行またはnull挿入行を持つTableViewに関連しています。詳細については、cellForRowメソッドを投稿してください。 – CodeChanger

+0

Hm、@vadian、どうしてですか?これは私が自動更新を実装するために使用した方法です。良い? – danilabagroff

答えて

1

問題の直接の原因は、あなたがnewIndexPathを使用する必要があるときに、行の更新のためのindexPathを使用していることです。

理由はindexPath前に任意の挿入インデックスであるか、削除してnewIndexPath後の挿入や削除指標であるということです。

あなたはfetchedResultsControllerからのtableViewまたはcollectionViewを更新し、それ決してクラッシュを持っているしたい場合は、これはあなたがそれを行う方法です: は5つの変更可能なオブジェクト持っている - rowInsert、rowDelete、rowUpdate、sectionInsert、sectionDeleteを。 rowInsert、rowDeleteおよびrowUpdateは、indexPathの可変配列です(つまり、NSMutableArray<NSIndexPath*>*)。 sectionInsertとsectionDeleteは可変インデックスセット(すなわちNSMutableIndexSet*)です。 controllerWillChangeContentで配列をクリアします。それぞれの変更に対して、適切なindexPathを追加します。挿入および更新用にはnewIndexPathを、使用する場合はindexPathを使用し、移動の場合はnewIndexPathをrowInsertに、indexPathをrowDeleteに追加します。 controllerDidChangeContentでは、rowInsertとsectionInsertを昇順に並べ替え、sectionDeleteとrowDeleteを降順にソートします。 rowUpdateは、その順番どおりに実行することができます。次に、rowDelete、sectionDelete、sectionInsert、rowInsert、rowUpdateの順に変更を適用します。

関連する問題