我以为我是got it。但是我在我的应用程序中发现的新崩溃说不然。因此当 newIndexPath 为非零并且与NSFetchedResultsChangeUpdate
中的 indexPath 不同时,任何人都知道-controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
的真正正确的代码吗?
答案 0 :(得分:9)
我刚刚在更新时遇到崩溃,并且当索引路径与从中检索单元格所需的索引路径不匹配时,似乎newIndexPath
被提供为获取的结果控制器对象的索引路径桌子。请考虑以下事项:
在上述情况下,假设您在相应的[tableView beginUpdates]
方法中使用[tableView endUpdates]
和controllerWill/DidChangeContent:
,则需要使用indexPath
参数来检索单元格从表更新(将是第0部分,索引14)和newIndexPath
参数,以从结果控制器(将是第0部分,索引13)检索要配置单元格的对象。
我认为它以这种方式工作,因为就结果控制器而言,删除似乎已经发生,但在表视图中没有发生(由于beginUpdates/endUpdates
调用包装更新)。如果你考虑上面的情况就行了,但似乎所有文档都没有考虑这种情况。
因此问题的答案是,您应该使用indexPath
参数从表视图中检索单元格,并使用newIndexPath
参数从提取的结果控制器中检索对象。请注意,如果没有插入或删除,则nil
似乎会传递newIndexPath
,因此在这种情况下,您必须同时使用indexPath
。
答案 1 :(得分:1)
如果NSFetchedResultsController的对象在"同一时间改变并移动" -controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
发送类型NSFetchedResultsChangeUpdate
(see here)。
我的解决方案是每次更新类型时更改类型以移动并且indexPath不等于newIndexPath
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView;
if (controller == self.fetchedResultsController) {
tableView = self.tableView;
}
else {
tableView = self.searchDisplayController.searchResultsTableView;
}
// type is "update" ---> should be "move"
if (type == NSFetchedResultsChangeUpdate && [indexPath compare:newIndexPath] != NSOrderedSame && newIndexPath != nil) {
type = NSFetchedResultsChangeMove;
}
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self fetchedResultsController:controller configureCell:(UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]withRowAnimation:UITableViewRowAnimationRight];
break;
}
}
之后你必须更新表格视图
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView endUpdates];
[self.tableView reloadData];
}
我希望这有用!