两个ManagedObjectContexts上的一个FetchRequest

时间:2014-10-15 10:21:06

标签: ios core-data nsmanagedobjectcontext nsfetchrequest

我有两个具有相同数据模型的托管对象上下文。唯一的区别是一个是只读,另一个是读/写。我想搜索可以在这两个托管对象上下文中的任何一个的对象。所以我创建了一个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似乎在两个托管对象上下文中都有效。每当您搜索挂起的更改时,公共(第二个)上下文都不会返回结果。

2 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

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

当fetchRequest改变时,使用委托NSFetchedResultsControllerDelegate。 代理代码可以是:

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