NSManagedObject:在单独的线程上创建

时间:2011-07-07 17:09:54

标签: objective-c cocoa core-data nsmanagedobject nsmanagedobjectcontext

我理解Core Data不是线程安全的,并且与上下文关联的NSManagedObjectContext和NSManagedObjects不能从线程传递给线程。

问题:

但是,如果我的主线程上有NSManagedObjectContext,我可以在后台线程上创建一个NSManagedObject对象(没有将它附加到任何上下文 - 也就是说,只需在NSManagedObject上调用alloc / init),然后传递NSManagedObject回到主线程并从那里添加到上下文?我已经回顾了关于Core Data并发性的文档,但是找不到任何说这个用法模式没问题的东西。

上下文:

我有一个执行复杂任务的后台线程,然后发布结果。结果是一个NSManagedObject子类,它包含一些属性:time,文件路径和成功或错误消息(作为字符串)。我想在后台线程上创建结果对象,然后将其扔回主线程并将其添加到Core Data上下文中,它将显示在tableView中。

如果我无法在后台线程上创建managedObject,那么我需要创建一个字典,将字典传递给主线程,读取键,从这些值创建managedObject等等。如果可能,在后台线程上创建managedObject。

1 个答案:

答案 0 :(得分:7)

更好的方法是每个线程都有一个上下文。这样每个线程都有自己的便笺本可以玩。然后,当后台线程完成时,告诉主线程更新其视图或ui表视图或每个人如何呈现数据。

发生更改时,您需要通知主线程。最大的问题是,不同线程和主线程之间的上下文彼此不了解。核心数据中有一种方法可以使上下文保持同步。如果要保存,后台线程上下文应该广播NSManagedObjectContextDidSaveNotification通知。

例如,在你的NSOperation中的main方法中,你可以这样做:

NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self
       selector:@selector(mergeChanges:)
           name:NSManagedObjectContextDidSaveNotification
         object:context];

mergeChanges将是您的NSOperation实例中的私有方法。

合并更改的示例

- (void)mergeChanges:(NSNotification *)notification
{
    ApplicationController *appController = [[NSApplication sharedApplication] delegate];
    NSManagedObjectContext *mainContext = [appController managedObjectContext];

    // Merge changes into the main context on the main thread
    [mainContext performSelectorOnMainThread:@selector(mergeChangesFromContextDidSaveNotification:)
                                  withObject:notification
                               waitUntilDone:YES];  
}