因爲iOS7之後 dispatch_get_current_queue 被廢棄,因此須要尋找一個替代的方案。html
發現 dispatch_get_current_queue 並無字面上那麼簡單。app
這個函數通常都會跟 dispatch_async 等API配合,async
可是試想一下,咱們本身建立的線程(好比 NSThread)跟 dispatch_queue_t 沒有關係,ide
那麼在咱們的線程中調用 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中,this
可是dispatch_get_current_queue仍是會返回一個dispatch_queue,spa
一個名字叫 com.apple.root.default-overcommit-priority 的 dispatch_queue!線程
可是!code
若是在 onPlay 中打斷點,你會發現,onPlay 並不在 com.apple.root.default-overcommit-priority 這個隊列中!
orm
[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中。