NSManagedObjectContext的performBlockAndWait:不在接收者的队列上执行

我注意到NSManagedObjectContextNSMainQueueConcurrencyType NSManagedObjectContext执行NSMainQueueConcurrencyType :并且在接收者(主)队列以外的队列上执行该块。

例如,如果我的parentContext的types为NSMainQueueConcurrencyType并且我的childContext的types为NSPrivateQueueConcurrencyType ,那么下面的代码将导致我的parentContext执行childContext的队列上的块:

 [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 }]; }]; 

这是预期的行为? 由于docs的状态为"performBlockAndWait: synchronously performs a given block on the receiver's queue."所以这当然令我感到困惑"performBlockAndWait: synchronously performs a given block on the receiver's queue."

你不应该担心什么线程块被执行。 什么performBlock:performBlockAndWait:方法保证是线程安全的 。 因此,从主线程调用performBlockAndWait:并不意味着将会有一个上下文切换到后台线程 – 这是非常昂贵的,它不是必需的。 如果在块的操作过程中(在主线程上)尝试执行一个块,它将被阻塞,直到当前正在执行的块完成。 在一天结束时,结果将与执行上下文切换相同,只会更快。 另一方面,调用performBlock:将在一个任意队列上排队,通常在后台线程上执行。

在上面的例子中,因为你执行了performBlockAndWait:你的私有队列上下文在主线程上执行你的块,就像主要的上下文块一样。 在第二个示例中,您将该块安排为asynchronous运行,以便在后台线程上执行。

你不应该通过它的名字来判断一个线程的队列。 要查看您是否在主队列中,可以使用dispatch_get_current_queue()并testing它是否等于dispatch_get_main_queue()