gpt4 book ai didi

ios - 合并 `NSManagedObjectContextDidSaveNotification` 后 NSFetchedResultsController 未显示所有结果

转载 作者:可可西里 更新时间:2023-11-01 05:01:33 25 4
gpt4 key购买 nike

我有一个 NSFetchedResultsController,它使用谓词获取对象:

isTrash == NO

大多数情况下这会按预期工作,但是当对象未被回收时,获取的结果 Controller 不会获取未回收的对象。

出了什么问题?

最佳答案

发生这种情况的原因是 mergeChangesFromContextDidSaveNotification: 处理更新对象的方式。 NSManagedObjectContext 记录在上下文中使用的对象,这些被称为注册对象(NSManagedObjectContext 有访问和有条件地获取注册对象的方法)。 mergeChangesFromContextDidSaveNotification: 仅处理在上下文中注册的对象的更新。这对解释问题原因的 NSFetchedResultsControllers 产生了链式 react 。

结果如下:

  1. FRC 设置了一个不匹配所有对象的谓词(从而防止不匹配谓词的对象在 FRC 上下文中注册)。

  2. 第二个上下文对对象进行了更改,这意味着它现在与 FRC 谓词相匹配。保存第二个上下文。

  3. FRCs 上下文处理 NSManagedObjectContextDidSaveNotification 但仅更新其注册的对象,因此它不会更新现在匹配 FRC 谓词的对象。

  4. FRC 不会在保存时执行另一次提取,因此不知道应该包含更新的对象。

修复

解决方案是在合并通知时获取所有更新的对象。这是一个示例合并方法:

-(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];
}
}
});
}

关于ios - 合并 `NSManagedObjectContextDidSaveNotification` 后 NSFetchedResultsController 未显示所有结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16296364/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com