根据KVO observing of NSMangedObject in a UITableViewCell,应该实现NSFetchedResultsControllerDelegate,而不是使用KVO来观察使用NSFetchedResultsController获取的托管对象的主要更改。
但我如何确定哪些属性已更改以及哪些对象?
我通过套接字流式传输数据更新,更新我的托管对象,并希望我的UI在所列对象的某些属性发生变化时进行相应更新。例如,我不想重绘整个表格或每个单元格,只显示显示已更改属性值的标签。
这是可行的,还是我应该求助于KVO但是以某种方式对其进行优化?
答案 0 :(得分:0)
您不应使用KVO更新CoreData对象。原因是:可以从两个单独的上下文中检索相同的对象记录,而KVO观察只会通过您的视图上下文通知您对象,让您不知道在不同上下文中对同一对象进行的更新。使用来自获取结果控制器的委托方法,您可以响应从其他上下文对对象所做的更改。这是从'CoreDataBooks'示例项目中获取的示例代码,是使用获取的结果控制器响应更改的正确方法:
/*
NSFetchedResultsController delegate methods to respond to additions, removals and so on.
*/
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller is about to start sending change notifications, so prepare the table view for updates.
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationAutomatic];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}