在iOS 5中,NSManagedObjectContext
有几个新方法,performBlock:
和performBlockAndWait:
。这些方法实际上是做什么用的?它们在旧版本中将替换什么?应该将什么样的块传递给他们?我该如何决定使用哪个?如果有人有一些使用示例,那就太好了。
在iOS 5中,NSManagedObjectContext
有几个新方法,performBlock:
和performBlockAndWait:
。这些方法实际上是做什么用的?它们在旧版本中将替换什么?应该将什么样的块传递给他们?我该如何决定使用哪个?如果有人有一些使用示例,那就太好了。
Answers:
如果MOC是使用或初始化的performBlock:
,performBlockAndWait:
则方法和用于将消息发送到您的NSManagedObjectContext
实例。如果对这些上下文类型之一进行任何操作(例如设置持久性存储或保存更改),则将在一个块中进行。NSPrivateQueueConcurrencyType
NSMainQueueConcurrencyType
performBlock:
会将块添加到后备队列,并安排其在其自己的线程上运行。该块将立即返回。您可以使用它对后备存储进行长时间持久的操作。
performBlockAndWait:
还将块添加到后备队列并安排其在自己的线程上运行。但是,直到该块执行完毕,该块才返回。如果直到知道操作是否成功就无法继续前进,那么这就是您的选择。
例如:
__block NSError *error = nil;
[context performBlockAndWait:^{
myManagedData.field = @"Hello";
[context save:&error];
}];
if (error) {
// handle the error.
}
请注意,因为我做了performBlockAndWait:
,所以我可以访问块外部的错误。performBlock:
将需要不同的方法。
NSManagedObjectContext现在为并发操作提供结构化支持。使用initWithConcurrencyType:创建托管对象上下文时,其线程(队列)关联具有三个选项
限制(NSConfinementConcurrencyType)。
这是默认值。您保证上下文将不会被创建线程以外的任何线程使用。(这与您在以前的版本中使用的线程要求完全相同。)
专用队列(NSPrivateQueueConcurrencyType)。
上下文创建和管理专用队列。在这里,上下文代替您创建和管理与上下文关联的线程或队列,而是由该上下文拥有该队列并为您管理所有详细信息(前提是您使用了如下所述的基于块的方法)。
主队列(NSMainQueueConcurrencyType)。
上下文与主队列相关联,因此被绑定到应用程序的事件循环中,但是在其他方面类似于基于私有队列的上下文。您将此队列类型用于链接到仅在主线程上使用的控制器和UI对象的上下文。
performBlockAndWait:
不阻塞主线程,对吗?它可以附加到主运行循环上令人困惑,但是它的名称使它看起来像让您等待。
它们允许您访问相同的managedObjectContext
跨线程。
我不确定自己是正确的,但这就是我的用法。
您使用performBlockAndWait
的就像“平常”。如果仅在一个线程上执行managedObjectContext,则不需要它。如果您在许多线程上执行它,那么您将需要performBlock
。
因此,如果您在主线程上,则不需要performBlockAndWait
为main做managedObjectContext
。至少我没有,而且还不错。
但是,如果您managedObjectContext
在其他线程上访问它,则需要做performBlockAndWait
。
这就是performBlock
和的目的performBlockAndWait
。
如果我在这里错了,请有人纠正我。当然,如果仅在一个线程上访问上下文,则只需使用默认值即可。
NSManagedObjectContext
:Core 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
是不是线程安全的,你不能跨线程访问它们。
performBlockAndWait:
和上下文一样在上下文线程上运行performBlock:
,但是使调用者的线程等待直到块执行完成。
po [NSThread currentThread]
在调试器的内部和外部performBlockAndWait:
调用中尝试过……哦,它确实在调用者线程上运行。谢谢你的链接。