我有一个 NSFetchedResultsController ,它使用谓词获取对象:
isTrash == NO
大多数情况下,这会按预期工作,但是当对象未被破坏时,获取的结果控制器不会获取未被破坏的对象。
出了什么问题?
发生这种情况的原因是由于mergeChangesFromContextDidSaveNotification:
处理更新的对象。NSManagedObjectContext
保存上下文中使用的对象的记录,这些被称为注册对象(NSManagedObjectContext
具有访问和有条件获取注册对象的方法)。mergeChangesFromContextDidSaveNotification:
仅处理在上下文中注册的对象的更新。这会产生连锁反应NSFetchedResultsControllers
这解释了问题的原因。
其结果如下:
FRC 使用不匹配所有对象的谓词设置(从而防止与谓词不匹配的对象在 FRC 上下文中注册)。
第二个上下文对对象进行更改,这意味着它现在与 FRC 谓词匹配。第二个上下文被保存。
FRC 上下文处理NSManagedObjectContextDidSaveNotification
但只更新其注册的对象,因此它不会更新现在与 FRC 谓词匹配的对象。
当进行保存时,FRC 不会执行另一次提取,因此不知道应包含更新的对象。
The fix
解决方案是在合并通知时获取所有更新的对象。这是一个合并方法的示例:
-(void)mergeChanges:(NSNotification *)notification {
dispatch_async(dispatch_get_main_queue, ^{
NSManagedObjectContext *savedContext = [notification object];
NSManagedObjectContext *mainContext = self.managedObjectContext;
BOOL isSelfSave = (savedContext == mainContext);
BOOL isSamePersistentStore = (savedContext.persistentStoreCoordinator == mainContext.persistentStoreCoordinator);
if (isSelfSave || !isSamePersistentStore) {
return;
}
[mainContext mergeChangesFromContextDidSaveNotification:notification];
//BUG FIX: When the notification is merged it only updates objects which are already registered in the context.
//If the predicate for a NSFetchedResultsController matches an updated object but the object is not registered
//in the FRC's context then the FRC will fail to include the updated object. The fix is to force all updated
//objects to be refreshed in the context thus making them available to the FRC.
//Note that we have to be very careful about which methods we call on the managed objects in the notifications userInfo.
for (NSManagedObject *unsafeManagedObject in notification.userInfo[NSUpdatedObjectsKey]) {
//Force the refresh of updated objects which may not have been registered in this context.
NSManagedObject *manangedObject = [mainContext existingObjectWithID:unsafeManagedObject.objectID error:NULL];
if (manangedObject != nil) {
[mainContext refreshObject:manangedObject mergeChanges:YES];
}
}
});
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)