通过新的NSPrivateQueueConcurrencyType获取核心数据背景

时间:2011-11-29 02:49:08

标签: core-data ios5

现在在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_sync(dispatch_get_main_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之前做到这一点。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

我正在尝试了解这个新API的实现方式。我通常的多线程核心数据模式是这样的:

通常在NSOperation中,但在此示例中使用dispatch_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似乎没有更少的代码输入。比“传统”线程更有优势吗?