【问题标题】:Core Data background fetching via new NSPrivateQueueConcurrencyType通过新的 NSPrivateQueueConcurrencyType 获取核心数据后台
【发布时间】:2012-01-08 11:11:06
【问题描述】:

现在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 之前实现。

【问题讨论】:

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

标签: core-data ios5


【解决方案1】:

我试图了解这个新 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 似乎并没有少多少需要键入的代码。与“传统”线程相比有何优势?

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2010-12-16
      • 2013-02-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-09
      • 1970-01-01
      相关资源
      最近更新 更多