NSFetchedResultsController在合并一个`NSManagedObjectContextDidSaveNotification`后不会显示所有结果 [英] NSFetchedResultsController is not showing all results after merging an `NSManagedObjectContextDidSaveNotification`

查看:151
本文介绍了NSFetchedResultsController在合并一个`NSManagedObjectContextDidSaveNotification`后不会显示所有结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an NSFetchedResultsController which fetches objects with a predicate:

isTrash == NO

大多数情况下,这是按预期工作,但是当一个对象未​​被破坏时,被抓取的结果控制器不会获取未破解的对象。

Most of the time this works as expected, but when an object gets untrashed the fetched results controller does not fetch the untrashed object.

发生了什么?

推荐答案

发生这种情况的原因是 mergeChangesFromContextDidSaveNotification: / code>处理更新的对象。 NSManagedObjectContext 保存在上下文中使用的对象的记录,这些被称为注册对象( NSManagedObjectContext 访问和有条件地获取注册对象的方法)。 mergeChangesFromContextDidSaveNotification:仅处理在上下文中注册的对象的更新。这对 NSFetchedResultsControllers 有解释问题原因的敲击效应。

The reason why this is happening is due to how mergeChangesFromContextDidSaveNotification: handles updated objects. NSManagedObjectContext keeps a record of objects which are in use in the context, these are referred to as registered objects (NSManagedObjectContext has methods for accessing and conditionally fetching registered objects). mergeChangesFromContextDidSaveNotification: only processes updates for objects which are registered in the context. This has a knock on effect for NSFetchedResultsControllers that explains the cause of the problem.

以下是其演奏方式:


  1. A FRC is setup with a predicate that doesn't match all objects (thus preventing the objects which do not match the predicate from being registered in the FRCs context).

第二个条件是不能匹配所有对象的谓词上下文对对象进行更改,这意味着它现在与FRC谓词匹配。第二个上下文被保存。

A second context makes a change to an object which means that it now matches the FRCs predicate. The second context is saved.

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

The FRCs context processes the NSManagedObjectContextDidSaveNotification but only updates its registered objects, therefore it does not update the object which now matches the FRC predicate.

当有保存时,FRC不执行另一个提取,因此不知道

The FRC does not perform another fetch when there's a save, therefore isn't aware that the updated object should be included.



修复



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

The fix

The solution is to fetch all updated objects when merging the notification. Here's an example merge method:

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

这篇关于NSFetchedResultsController在合并一个`NSManagedObjectContextDidSaveNotification`后不会显示所有结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆