两个 ManagedObjectContexts 上的一个 FetchRequest

Posted

技术标签:

【中文标题】两个 ManagedObjectContexts 上的一个 FetchRequest【英文标题】:One FetchRequest on two ManagedObjectContexts 【发布时间】:2014-10-15 10:21:05 【问题描述】:

我有两个具有相同数据模型的托管对象上下文。唯一的区别是一个是只读的,另一个是读/写的。我想搜索可以在这两个托管对象上下文中的任何一个中的对象。所以我创建了一个 fetchrequest 并想在两个托管对象上下文中使用 fetchrequest。

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
[fetchRequest setIncludesPendingChanges:YES];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name=%@", name];

NSError *error = nil;
NSArray *privateobjects = [self.privateManagedObjectContext executeFetchRequest:fetchRequest error:&error];
if (privateobjects && privateobjects.count > 0)

    return privateobjects[0];


NSArray *publicobjects = [self.publicManagedObjectContext executeFetchRequest:fetchRequest error:&error];
if (publicobjects && publicobjects.count > 0)

    return publicobjects[0];


return nil;

以上代码不返回来自公共托管对象上下文的结果。我可以通过重新创建 fetchrequest 来解决这个问题。所以我的问题是,为什么一个 fetchrequest 不能在两个托管对象上下文中工作?

编辑:经过更多研究,当保存两个上下文时,fetchrequest 似乎适用于两个托管对象上下文。每当您搜索挂起的更改时,公共(第二个)上下文都不会返回结果。

【问题讨论】:

【参考方案1】:

我相信您必须创建两次获取请求,因为它依赖于托管对象上下文。 NSFetchRequest(entityName:) 实际上是具有特定NSEntityDescription 的获取请求的简写,但没有托管对象上下文。使用 NSManagedObjectContext 方法执行 fetch 请求时在最后时刻填写的上下文。 (NSEntityDescription 工厂方法包括上下文)。

因此,您可能会尝试创建一个方便的方法来返回这种“不完整”的获取请求,然后在不同的上下文中使用它。 (不确定这是否有效,但如果有效,它将为您节省大约 2-3 行代码)。或者,只需编写再次创建获取请求的代码。

【讨论】:

谢谢!! “使用 NSManagedObjectContext 方法执行 fetch 请求时最后时刻填写的上下文。(NSEntityDescription 工厂方法包括上下文)。”这正是我想要的。【参考方案2】:

您必须在 NSFetchRequest 实例中添加数据更改通知。

委托 NSFetchedResultsControllerDelegate 在不同的 fetchRequest 改变时使用。 委托代码可以是:

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    
        [[NSNotificationCenter defaultCenter] postNotificationName:kNotification_LocalContactStorageSaved 
                                                            object:nil];
    

    #pragma mark - context merge from other MOC

    - (void)contextDidSave:(NSNotification *)notification
    
        NSManagedObjectContext *sender = (NSManagedObjectContext *)[notification object];
            dispatch_sync(dispatch_get_main_queue(), ^
                [managedObjectContext_localContacts mergeChangesFromContextDidSaveNotification:notification];
            );
    

【讨论】:

我不知道你想在这里解决什么。我的问题与 NSFetchedResultsController 无关,上下文是独立的,它们永远不会合并。 您可以在私有管理上下文中使用保存,将更改保存到商店。公开的将从存储中获取数据(不使用缓存) 刚刚测试过了。如果我只保存第一个上下文,我仍然无法从第二个上下文中检索挂起的更改。

以上是关于两个 ManagedObjectContexts 上的一个 FetchRequest的主要内容,如果未能解决你的问题,请参考以下文章

处理父子 managedObjectContexts 的应用程序崩溃

RestKit 0.20 和 ManagedObjectContexts

锁定 managedObjectContext

核心数据 - 在后台保存到磁盘上的持久存储

Core Data 3 托管对象上下文

计算两个时间差的两个函数