4

真的很简单的问题,我的核心数据 UIManagedDocument 是在主线程上创建的,我想知道的是,当我调用 performBlock 时,该阻塞队列/在主线程(创建托管文档的同一线程)上运行吗?

dispatch_queue_t backgroundQueue = dispatch_queue_create("DownloadQueue", NULL);
dispatch_async(backgroundQueue, ^{
    // Get data from web
    [document.managedObjectContext performBlock:^{
        // Add data to Core Data
    }];
});
4

2 回答 2

2

你可以阅读苹果发行说明:CoreData Release Notes for iOS5

您可以使用限制模式来使用上下文,就像在 OS X v10.7 和 iOS 5 之前一样。您可以直接发送上下文消息;您可以确保从正确的队列发送消息。

您可以结合使用基于队列的并发类型和两个新方法来使用上下文:performBlock: 和 performBlockAndWait:。您将“标准”消息分组以发送到块中的上下文(包括初始化,例如设置持久存储协调器等),以传递给这些方法之一。一个例外是:如果您的代码在主线程上执行,您可以直接在主队列样式上下文中调用方法,而不是使用基于块的 API。

performBlock: 和 performBlockAndWait: 确保块操作在为上下文指定的队列上执行。performBlock: 方法立即返回,上下文在其自己的线程上执行块方法。使用 performBlockAndWait: 方法,上下文仍然在自己的线程上执行块方法,但该方法在块执行之前不会返回。

重要的是要认识到块是作为一个独特的工作体执行的。一旦您的块结束,其他任何人都可以将另一个块加入队列、撤消更改、重置上下文等等。因此块可能非常大,并且通常以调用 save: 结束。

于 2012-10-04T20:57:39.163 回答
0

当使用UIManagedDocumentmanagedObjectContext 创建时(就像在 OS X v10.7 和 iOS 5 之前一样),使用等同于默认的 Confinement type NSConfinementConcurrencyType。简单地说,这种并发类型指定上下文将不会用于除最初创建上下文的线程之外的任何其他线程。

在这种情况下,UIManagedDocument(及其上下文)是在主线程上创建的,消息传递performBlock:将在主线程上执行关联的块。通过使用performBlock:,您实际上不必知道 managedObjectContext 是在哪个线程上创建的,消息传递performBlock:将始终在上下文所在的同一线程上执行其关联的块。

于 2012-10-08T12:24:36.550 回答