NSManagedObjectContext的performBlock有什么用?


67

在iOS 5中,NSManagedObjectContext有几个新方法,performBlock:performBlockAndWait:。这些方法实际上是做什么用的?它们在旧版本中将替换什么?应该将什么样的块传递给他们?我该如何决定使用哪个?如果有人有一些使用示例,那就太好了。


您是说“ NSManagedObjectContext”吗?
MikeG 2012年

我很确定他做到了。也许内文(Nevan)可以在以下位置提出建议:stackoverflow.com/tags/nsmanagedobjectcomplex/synonyms
Bjinse 2012年

修复了该拼写错误,感谢您的注意。

Answers:


124

如果MOC是使用或初始化的performBlock:performBlockAndWait:则方法和用于将消息发送到您的NSManagedObjectContext实例。如果对这些上下文类型之一进行任何操作(例如设置持久性存储或保存更改),则将在一个块中进行。NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType

performBlock:会将块添加到后备队列,并安排其在其自己的线程上运行。该块将立即返回。您可以使用它对后备存储进行长时间持久的操作。

performBlockAndWait:还将块添加到后备队列并安排其在自己的线程上运行。但是,直到该块执行完毕,该块才返回。如果直到知道操作是否成功就无法继续前进,那么这就是您的选择。

例如:

__block NSError *error = nil;
[context performBlockAndWait:^{
    myManagedData.field = @"Hello";
    [context save:&error];
}];

if (error) {
    // handle the error.
}

请注意,因为我做了performBlockAndWait:,所以我可以访问块外部的错误。performBlock:将需要不同的方法。

iOS 5核心数据发行说明中

NSManagedObjectContext现在为并发操作提供结构化支持。使用initWithConcurrencyType:创建托管对象上下文时,其线程(队列)关联具有三个选项

  • 限制(NSConfinementConcurrencyType)。

    这是默认值。您保证上下文将不会被创建线程以外的任何线程使用。(这与您在以前的版本中使用的线程要求完全相同。)

  • 专用队列(NSPrivateQueueConcurrencyType)。

    上下文创建和管理专用队列。在这里,上下文代替您创建和管理与上下文关联的线程或队列,而是由该上下文拥有该​​队列并为您管理所有详细信息(前提是您使用了如下所述的基于块的方法)。

  • 主队列(NSMainQueueConcurrencyType)。

    上下文与主队列相关联,因此被绑定到应用程序的事件循环中,但是在其他方面类似于基于私有队列的上下文。您将此队列类型用于链接到仅在主线程上使用的控制器和UI对象的上下文。


感谢你的回答。performBlockAndWait:不阻塞主线程,对吗?它可以附加到主运行循环上令人困惑,但是它的名称使它看起来像让您等待。

另外,什么是“后备队列”和“长时间持久操作”。对不起所有问题,我对线程一无所知。

2
@MikeG我认为您可能已将事情颠倒了(或在阅读本文时被颠倒了)。performBlockAndWait将阻止主线程或其他线程调用的任何线程,并且不在乎MOC与哪个线程相关联。还是我误读了你?
RonLugge 2012年

@RonLugg,谢谢你叫我。我现在按照您阅读的方式进行阅读。
MikeG 2012年

1
我需要在peformBlock中创建我的ManagedObject吗?
thierryb

-3

它们允许您访问相同的managedObjectContext跨线程。

我不确定自己是正确的,但这就是我的用法。

您使用performBlockAndWait的就像“平常”。如果仅在一个线程上执行managedObjectContext,则不需要它。如果您在许多线程上执行它,那么您将需要performBlock

因此,如果您在主线程上,则不需要performBlockAndWait为main做managedObjectContext。至少我没有,而且还不错。

但是,如果您managedObjectContext在其他线程上访问它,则需要做performBlockAndWait

这就是performBlock和的目的performBlockAndWait

如果我在这里错了,请有人纠正我。当然,如果仅在一个线程上访问上下文,则只需使用默认值即可。


这两种方法与您在调用它们的线程上执行指令的行为有关。一个阻塞调用线程等待返回,另一个阻塞(即使工作仍在运行,调用也会立即返回)。可以从任何线程中调用。
比尔·帕特森

-1:这个答案是完全错误的。要在文档开始- NSManagedObjectContextCore Data uses thread (or serialized queue) confinement to protect managed objects and managed object contexts. A consequence of this is that a context assumes the default owner is the thread or queue that allocated it—this is determined by the thread that calls its init method. You should not, therefore, initialize a context on one thread then pass it to a different thread.因此,NSManagedObjectContexts不是线程安全的,你不能跨线程访问它们。
JRG-Developer 2013年

2
@BradThomasperformBlockAndWait:和上下文一样在上下文线程上运行performBlock:,但是使调用者的线程等待直到块执行完成。
tonytony 2013年

1
@tonytony我想澄清这一点,所以我向您挑战...您说的话与在该主题上发布的令人信服的最佳答案(和令人信服的问题)不一样…… stackoverflow.com
Brad Thomas

1
@BradThomas我po [NSThread currentThread]在调试器的内部和外部performBlockAndWait:调用中尝试过……哦,它确实调用者线程上运行。谢谢你的链接。
tonytony 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.