NSManagedObjectContext的performBlockAndWait:不在接收者的队列上执行
我注意到NSManagedObjectContext
和NSMainQueueConcurrencyType
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()
。