dispatch_get_current_queue 廢棄


由於iOS7以后 dispatch_get_current_queue 被廢棄,所以需要尋找一個替代的方案。

發現 dispatch_get_current_queue 並沒有字面上那么簡單。

這個函數一般都會跟 dispatch_async 等API配合,

但是試想一下,我們自己創建的線程(比如 NSThread)跟 dispatch_queue_t 沒有關系,

那么在我們的線程中調用 dispatch_get_current_queue 會返回什么呢?

 

     [NSThread detachNewThreadSelector:@selector(onPlay:) toTarget:self withObject:nil];

     - (void)onPlay
     {
         dispatch_queue_t dispatch_queue = dispatch_get_current_queue(); // 這里會返回什么?
     }

 

在上面的代碼中,我們並沒有將onPlay顯示投遞到某一個dispatch_queue中,

但是dispatch_get_current_queue還是會返回一個dispatch_queue,

一個名字叫 com.apple.root.default-overcommit-priority 的 dispatch_queue!

但是!

如果在 onPlay 中打斷點,你會發現,onPlay 並不在 com.apple.root.default-overcommit-priority 這個隊列中!

 

     [NSThread detachNewThreadSelector:@selector(onPlay:) toTarget:self withObject:nil];

     - (void)onPlay
     {
          NSLog(@"1");
          dispatch_async(dispatch_get_current_queue(), ^{
               NSLog(@"2");
          }); 
     }


兩句NSLog將不在同一個queue中打印!

 

好,以下分析dispatch_get_current_queue更深一層的行為。


先分析官方文檔的說法:

函數聲明:

     dispatch_queue_t dispatch_get_current_queue(void);


描述(description):


     Returns the queue on which the currently executing block is running.

     返回當前所在的隊列(dispatch_queue_t)。


詳述(discussion):


     This function is defined to never return NULL.

     When called from outside of the context of a submitted block, 

     this function returns the main queue if the call is executed from the main thread. 

     If the call is made from any other thread, this function returns the default concurrent queue.


     當調用這個函數的地方不是在某個已提交到隊列的block內部時,

     如果在主線程中被調用,則返回main_queue。

     如果不在主線程中調用,則返回一個默認的並行隊列。


我們先嘗試將線程分成三種類型:

主線程

     只有一個,並且存在一個與該線程綁定的 dispatch_queue,名字是 com.apple.main-thread,可以通過 dispatch_get_main_queue 得到。


dispatch_queue 線程

     dispatch_queue 自己創建的線程,該線程當然是與創建它的 dispatch_queue 綁定。


其他線程

     通過NSThread,POSIX,[NSObject performSelectorInBackground]等接口創建出來的線程,沒有與之綁定的 dispatch_queue。


那么官方文檔說的其他線程(any other thread),指的就是除主線程,dispatch_queue 線程之外的線程。

這些線程沒有與之綁定的 dispatch_queue,所以會返回一個 “默認的並行隊列(default concurrent queue)”。

這是個什么東西呢?我們用文章開頭的代碼,打印出這個隊列的名字。

 

     [NSThread detachNewThreadSelector:@selector(onPlay:) toTarget:self withObject:nil];

     - (void)onPlay
     {
         dispatch_queue_t dispatch_queue = dispatch_get_current_queue();
         NSLog(@"%s", dispatch_queue_get_label(dispatch_queue));
     }

其結果是:com.apple.root.default-overcommit-priority。

也就是說,如果執行 dispatch_get_current_queue 的線程沒有與之綁定的隊列的時候,

會返回一個 com.apple.root.default-overcommit-priority 的隊列,這個隊列跟該線程沒有關系。

可以理解為 dispatch_get_current_queue 這個函數的例外情況。

可以猜測 dispatch_get_current_queue 被廢棄的原因就是這個函數不一定總是有意義的。


每一個well-known global queue 都有一個與之對應的 overcommit 類型的queue。

 overcommit 類型的 queue 具體是什么用途,為什么會分開暫時還不知道。


整理:

以下是iOS應用程序中默認創建的隊列:


     優先級                                             名稱                                                                                               

well-known global queue

     High priority                         (com.apple.root.high-priority)                                             

     Default priority                     (com.apple.root.default-priority)                                                     

     Low priority                          (com.apple.root.low-priority)                                                      

     Background priority              (com.apple.root.background-priority)                                             


overcommit global queue

     High priority                          (com.apple.root.high-overcommit-priority)

     Default priority                      (com.apple.root.default-overcommit-priority)

     Low priority                           (com.apple.root.low-overcommit-priority)

     Background priority               (com.apple.root.background-overcommit-priority)


main queue

     Main-Thread                          (com.apple.main-thread)    


各種API獲取到的隊列:


dispatch_get_global_queue                              相應優先級的 well-known global queue

dispatch_get_main_queue                                com.apple.main-thread    


各種情況下調用dispatch_get_current_queue得到的隊列:


主線程中                                                        com.apple.main-thread    

NSThread                                                      com.apple.root.default-overcommit-priority

pthread                                                          com.apple.root.default-overcommit-priority

[NSObject performSelectorInBackground]     com.apple.root.default-overcommit-priority

NSOperationQueue                                       com.apple.root.default-priority


NSOperationQueue使用GCD實現,具體內部會使用 com.apple.root.default-priority 隊列來執行任務。

NSBlockOperation或者NSInvocationOperation都會被投遞到這個dispatch_queue中。



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM