Core data 通过新的NSPrivateQueueConcurrencyType获取核心数据后台

Core data 通过新的NSPrivateQueueConcurrencyType获取核心数据后台,core-data,ios5,Core Data,Ios5,现在在iOS5中真的这么简单吗 我曾在AppDelegate中使用以下代码执行后台提取: dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL); dispatch_async(downloadQueue, ^{ self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.manage

现在在iOS5中真的这么简单吗

我曾在AppDelegate中使用以下代码执行后台提取:

dispatch_queue_t downloadQueue = dispatch_queue_create("DownloadQueue", NULL);
dispatch_async(downloadQueue, ^{
        self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:self.managedObjectContext];
        [self.myDownloadClass download];
    });

dispatch_release(downloadQueue);
我的下载类执行NSURLConnection来获取一些XML数据,使用NSXMLParser来解析数据,然后更新核心数据中的复杂模式。我总是切换到主线程来实际更新核心数据。乱七八糟的代码,有很多调用dispatch\u sync(dispatch\u get\u main\u queue()

我的新代码如下所示:

NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:self.managedObjectContext];

[child performBlock:^{
    self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child];
    [self.myDownloadClass download];
    }];
同时对我的AppDelegate中的其他一些代码进行了一些小的更改,以将父模型对象上下文类型设置为NSMainQueueConcurrencyType:

- (NSManagedObjectContext *)managedObjectContext
{
    if (__managedObjectContext != nil)
    {
        return __managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil)
    {
        __managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [__managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
    return __managedObjectContext;
}
它似乎工作得很好。整个更新过程仍然在一个单独的线程中运行,但我不必创建线程。看起来很神奇

请记住,如果要将更改提交到物理核心数据文件,还需要在父上下文上调用save:


我在这里并没有问任何问题。我发布这篇文章是为了帮助其他人,因为我在搜索新的iOS5托管对象上下文方法时发现的所有内容都只提供了高级细节,没有代码示例,而且所有其他在后台获取核心数据的搜索都是旧的,有时非常旧,并讨论如何在iOS5之前执行

我试图理解这个新API是如何实现的。我通常使用的多线程核心数据模式如下:

NSManagedObjectContext *child = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[child setParentContext:self.managedObjectContext];

[child performBlock:^{
    self.myDownloadClass = [[MyDownloadClass alloc]initInManagedObjectContext:child];
    [self.myDownloadClass download];
    }];
通常在
NSOperation
中,但在本例中使用
dispatch\u async
进行简化:

dispatch_queue_t coredata_queue; // some static queue

dispatch_async(coredata_queue, ^() {
    // get a new context for this thread, based on common persistent coordinator
    NSManagedObjectContext *context = [[MyModelSingleton model] threadedContext];

    // do something expensive

    NSError *error = nil;
    BOOL success = [context save:&error];
    if (!success) {
        // the usual.
    }

    // callback on mainthread using dispatch_get_main_queue();
});
然后,主线程将根据
NSManagedObjectContextDidSaveNotification
更新UI以合并主上下文

新的API似乎是这个模式的包装器,
child
上下文看起来只是从其父级获取持久性协调器来创建新的上下文。在init上指定
NSPrivateQueueConcurrencyType
将确保在私有队列上执行
performBlock
参数


新的API似乎没有太少的代码要输入。与“传统”线程相比有什么优势吗?

是的-现在真的很容易(在iOS 5.0中)。对于iOS 4兼容性,前面的障碍仍然存在,但文档在线程限制方面还不错。也许你应该将其添加到wiki部分?

然后你需要保存更改!你就是那个人!非常感谢分享:我假设在下载类中,你通过上的performBlock:在父moc上调用save:父级,保存到子级moc后对吗?