我注意到NSManagedObjectContext
可能NSMainQueueConcurrencyType
到performBlockAndWait
:并且在接收者(主)队列以外的队列上执行阻止。
例如,如果我的parentContext
类型为childContext
且{{1} parentContext
,则以下代码会导致我NSMainQueueConcurrencyType
执行childContext
队列中的阻止类型为NSPrivateQueueConcurrencyType
:
[childContext performBlockAndWait:^{
//Thread 1, Queue: NSManagedObjectContext Queue
[parentContext performBlockAndWait:^{
//Thread 1, Queue: NSManagedObjectContext Queue
//This is the same queue as the child context's queue
}];
}];
相反,以下代码按预期工作 - 我的parentContext
执行主队列上的块:
[childContext performBlock:^{
[parentContext performBlockAndWait:^{
//Thread 1, Queue: com.apple.main-thread
}];
}];
这是预期的行为吗?自从文档陈述"performBlockAndWait: synchronously performs a given block on the receiver’s queue."
答案 0 :(得分:3)
您不应该担心执行哪些线程块。 performBlock:
和performBlockAndWait:
方法保证的是线程安全性。因此,从主线程调用performBlockAndWait:
并不意味着会有一个上下文切换到后台线程 - 它非常昂贵而且不需要。如果在块的操作期间(在主线程上),执行尝试以执行块,则它将被阻塞,直到当前正在执行的块完成。在一天结束时,结果将与执行上下文切换的结果相同,但速度更快。另一方面,调用performBlock:
会将块排在任意队列上,通常在后台线程上执行。
在上面的示例中,由于您performBlockAndWait:
,您的私有队列上下文在主线程上执行您的块,主上下文块也是如此。在第二个示例中,您将调度块以异步方式运行,因此它将在后台线程上执行。
你不应该用它的名字判断一个线程的队列。要查看您是否在主要队列中,可以使用dispatch_get_current_queue()
并测试它是否等于dispatch_get_main_queue()
。