忍受着我,這是要做一些解釋。我有一個如下所示的函數。dispatch_sync與主隊列上的dispatch_async
上下文:「aProject」是名爲LPProject的核心數據實體,其數組名爲「memberFiles」,其中包含另一個名爲LPFile的Core Data實體的實例。每個LPFile代表磁盤上的一個文件,我們想要做的就是打開這些文件並解析它的文本,尋找指向OTHER文件的@import語句。如果我們找到@import語句,我們希望找到它們指向的文件,然後通過向表示第一個文件的核心數據實體添加關係,將該文件「鏈接」到該文件。由於所有這些都可能需要一些時間處理大文件,我們將使用GCD從主線程中刪除它。
- (void) establishImportLinksForFilesInProject:(LPProject *)aProject {
dispatch_queue_t taskQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
for (LPFile *fileToCheck in aProject.memberFiles) {
if (//Some condition is met) {
dispatch_async(taskQ, ^{
// Here, we do the scanning for @import statements.
// When we find a valid one, we put the whole path to the imported file into an array called 'verifiedImports'.
// go back to the main thread and update the model (Core Data is not thread-safe.)
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"Got to main thread.");
for (NSString *import in verifiedImports) {
// Add the relationship to Core Data LPFile entity.
}
});//end block
});//end block
}
}
}
現在,這裏的事情變得怪異:
此代碼的工作,但我看到一個奇怪的問題。如果我在有幾個文件(大約20個)的LPProject上運行它,它可以完美運行。但是,如果我在具有更多文件(例如60-70)的LPProject上運行它,它確實運行正確NOT。我們永遠不會回到主線程,NSLog(@"got to main thread");
從不出現,應用程序掛起。但是,(這是真正奇怪的地方)---如果我在小型項目FIRST上運行代碼然後在大型項目上運行代碼,那麼一切都很完美。只有當我在大型項目上運行代碼時,纔會出現問題。
而這裏的踢球,如果我改變第二派遣線到這一點:
dispatch_async(dispatch_get_main_queue(), ^{
(也就是說,使用async
代替sync
到塊分派到主隊列),一切正常,所有的時間。完美。無論項目中有多少文件!
我無法解釋這種行爲。任何幫助或提示下一步測試將不勝感激。
注意:爲了簡潔起見,我已經編寫了「掃描」和「核心數據條目」代碼片段。但是,我幾乎肯定他們不是罪魁禍首,因爲如果我將所有內容放在單個線程中,並且他們在上述多線程情況下完美工作(通過首先運行一個小型項目「預熱」所有內容和/或在主隊列上使用dispatch_async()而不是dispatch_sync())。 – Bryan
聽起來就像是碰到了一個死鎖問題 –
當你處於這種狀態時,你應該對你的應用程序運行示例或工具來查看其他線程都在做什麼。如果他們陷入僵局,發生的事情應該更加明顯。 –