dispatch_get_main_queue 卡死的問題(已解決)

dispatch_get_main_queue 卡死的問題

這兩天做項目的過程中遇到dispatch_get_main_queue卡死的問題,已解決,在此記錄下。

其主要現象是,我有一個view,在創建的時候需要刷新,而這個view是在windowDidLoad裏面創建的,我在子線程裏面調用dispatch_sync(dispatch_get_main_queue(), ^{})方法刷新了view,結果window一打開,就出現了卡死現象。

其主要原因是主線程消息隊列引起的,dispatch_get_main_queue()是一個串行的隊列,即先進先出,系統維護的dispatch_get_main_queue()執行viewDidLoad,先進棧,所以應該是viewDidLoad執行完畢後再執行其它任務,但是現在,viewDidLoad裏面又調用了dispatch_sync(dispatch_get_main_queue(), ^{}),所以viewDidLoad會等待dispatch_sync調用的dispatch_get_main_queue()執行完畢,而dispatch_sync調用的dispatch_get_main_queue()又在等待viewDidLoad執行完畢,就這樣進入了死循環。

我嘗試先讓viewDidLoad執行完,然後再創建我的view,結果還是不行,應該是這種衝突不止在viewDidLoad裏面發生,在其它刷新view時,系統維護的dispatch_get_main_queue()和自己維護的dispatch_get_main_queue()都很容易產生衝突。

最後換了一個處理方法,拋棄了dispatch_get_main_queue(),使用performSelectorOnMainThread函數,結果就沒有問題了。

dispatch_get_main_queue是在the main run loop裏面的,會有block;而performSelectorOnMainThread是在the default run loop mode裏面的,會有一個模式切換。想必也是這個原因纔不會引起的卡死吧。

另外,還有dispatch_async異步操作,也不會發生鎖死,比如:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
    // 處理  
    dispatch_async(dispatch_get_main_queue(), ^{  
        // 更新UI  
    });  
}); 

再來簡單解釋下兩個隊列:
dispatch_get_main_queue:獲取主隊列,會將任務插入主線程的RunLoop當中去執行,是個串行隊列,可以使用它來更新UI。
dispatch_get_global_queue:是一個全局的並行隊列,有高、默認、低和後臺4個優先級,由第一個參數決定,第二個參數是保留字段備用,一般爲0。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章