如何使用非 nil parentContext 创建 NSManagedObjectContext?

Posted

技术标签:

【中文标题】如何使用非 nil parentContext 创建 NSManagedObjectContext?【英文标题】:How to create a NSManagedObjectContext with a non nil parentContext? 【发布时间】:2013-03-15 11:41:03 【问题描述】:

如何创建一个NSManagedObjectContext,它有一个在不同队列/线程上运行的非nil parentContext

UIManagedDocument 的 managedObjectContext 确实有这个,但我不知道如何在不使用 UIManagedDocument 的情况下复制它。

这是我正在使用的代码,它会生成一个managedObjectContext,其parentContext 属性是nil

-(NSManagedObjectContext *)context

    if (_context == nil)
        _context = [[NSManagedObjectContext alloc] init];
        _context.persistentStoreCoordinator = self.storeCoordinator;
    
    return _context;


-(NSPersistentStoreCoordinator *) storeCoordinator
    if (_storeCoordinator == nil) 
        _storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.model];

        NSError *err = nil;
        if (![_storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                             configuration:nil
                                                       URL:self.dbURL
                                                   options:nil
                                                     error:&err ]) 

            NSLog(@"Error while adding a Store: %@", err);
            return nil;

        
    
    return _storeCoordinator;


-(NSManagedObjectModel *) model

    if (_model == nil) 
        _model = [[NSManagedObjectModel alloc] initWithContentsOfURL:self.modelURL];
    
    return _model;

【问题讨论】:

What have you tried? 我刚刚编辑了问题以添加一些代码。 您可以将任何 NSManagedObjectContext 的父上下文设置为任何其他 NSManagedObjectContext。 mycontext.parent = parentContext; 【参考方案1】:

您只需分配子上下文并设置其父上下文即可创建子上下文:

NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] init];
[childContext setParentContext:[self managedObjectContext]];

持久存储协调器是从父上下文继承的,所以这就是创建子上下文所需的全部内容。 父上下文必须使用一种基于队列的并发类型。这意味着您上面创建上下文的代码必须更改为:

_context = [[NSManagedObjectContext alloc] initWithConcurrencyType: NSMainQueueConcurrencyType];

还有NSPrivateQueueConcurrencyType。哪个更好取决于您应用的设计。

在不同的队列/线程上运行是另一回事。这从来都不是自动的。您的代码在您调用它的任何队列或线程上运行。 Core Data 的直接支持仅限于使用基于队列的并发类型之一——但是您需要确保使用 performBlock:performBlockAndWait: 以确保上下文的操作实际发生在正确的队列上。

【讨论】:

【参考方案2】:

创建NSManagedObjectContext 后,如果您需要将其作为子上下文,则必须分配父上下文。

[newContext setParentContext:mainThreadManagedObjectContext];

在这种情况下,您甚至不必分配持久存储。来自文档:

您现在可以使用 setParentContext: 指定父托管对象上下文,而不是为托管对象上下文指定持久存储协调器。这意味着 fetch 和 save 操作由父上下文而不是协调器进行调解。

【讨论】:

以上是关于如何使用非 nil parentContext 创建 NSManagedObjectContext?的主要内容,如果未能解决你的问题,请参考以下文章

NSError 为 nil 但进入非 nil 状态

Go 语言中的 nil 切片 vs 非 nil 切片 vs 空切片

通过应用过滤器摆脱 nil 后将类型更改为非可选

在上下文之间传递 objectID 时未触发 to-many 错误

从预期返回非空值的方法返回 Nil

防止 Obj-C 代码将 `nil` 传递给具有非可选参数的 Swift 方法