2013-10-17 61 views
4

我注意到NSManagedObjectContext可能與NSMainQueueConcurrencyTypeperformBlockAndWait:並且在接收者(主)隊列以外的隊列上執行該塊。NSManagedObjectContext的performBlockAndWait:不在接收者的隊列上執行

例如,下面的代碼的結果在我parentContext執行對childContext的隊列中的塊,如果我的parentContextNSMainQueueConcurrencyType類型的我的childContextNSPrivateQueueConcurrencyType類型:

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

這是對EXP行爲?自從文檔狀態

+0

您如何檢查代碼的運行隊列? –

回答

3

你肯定不會擔心什麼線程塊被執行。 performBlock:performBlockAndWait:方法保證的是線程安全。因此,從主線程調用performBlockAndWait:並不意味着會有一個上下文切換到後臺線程 - 這是非常昂貴的,而且不是必需的。如果在塊的操作過程中(在主線程上)嘗試執行一個塊,它將被阻塞,直到當前正在執行的塊完成。在一天結束時,結果將與執行上下文切換相同,但速度更快。另一方面,調用performBlock:會將該塊排列在任意隊列上,通常在後臺線程上執行。

在上面的例子中,由於您的performBlockAndWait:,您的私有隊列上下文在主線程上執行您的塊,就像主要上下文塊一樣。在第二個示例中,您將該塊安排爲異步運行,以便它在後臺線程上執行。

您不應該通過它的名稱來判斷線程的隊列。要查看您是否在主隊列中,可以使用dispatch_get_current_queue()並測試它是否等於dispatch_get_main_queue()

+2

這種if行爲是爲什麼dispatch_get_current_queue被棄用。基本上,如果你認爲自己關心隊列的身份,那麼你可能做錯了事情,因爲並不總是有一個正確的答案。 –

+0

是的,我同意。做你的代碼是正確的,不會有任何問題。 –

+1

這並不能真正回答我的問題。爲了澄清,我的問題是:爲什麼具有NSMainQueueConcurrencyType的'NSManagedObjectContext'在docs state:'「performBlockAndWait:同步執行給定的塊上的主隊列之外的任何隊列上執行'performBlockAndWait:接收者的隊列。「在這種情況下,接收者的隊列應該是主隊列。我已經證實,它並不總是主隊列,如上所示。 –

相關問題