dispatch_get_current_queue 废弃

因为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中。


相关文章
相关标签/搜索