iOS之《Effective Objective-C 2.0》读书笔记(46)

来源:互联网 发布:centos命令 desktop 编辑:程序博客网 时间:2024/06/05 16:21

第46条:不要使用dispatch_get_current_queue

1.有两个串行派发队列:

  • 到最内层的派发队列时,会死锁。A在等B,B在等A,A阻塞
-(void)demo1{      dispatch_queue_t queueA = dispatch_queue_create("com.lyk.queueA", NULL);      dispatch_queue_t queueB = dispatch_queue_create("com.lyk.queueB", NULL);      dispatch_sync(queueA, ^{         dispatch_sync(queueB, ^{            dispatch_sync(queueA, ^{               //......            });         });      });  }  

2.用dispatch_get_current_queue来检测:

  • 这样做依然死锁,dispatch_get_current_queue获取到的当前队列是queueB,所以结果依然执行针对queueA的同步派发操作
-(void)demo2{      dispatch_queue_t queueA = dispatch_queue_create("com.lyk.queueA", NULL);      dispatch_queue_t queueB = dispatch_queue_create("com.lyk.queueB", NULL);      dispatch_sync(queueA, ^{          dispatch_sync(queueB, ^{              dispatch_block_t block = ^{};              if (dispatch_get_current_queue() == queueA) {                  block();              } else {                  dispatch_sync(queueA, block);              }          });      });  }  

3.通过GCD所提供的功能来设定“队列特有数据“:

  • 可以把任意数据以键值对形式关联到队列中。如果根据指定的键获取不到关联数据,系统会沿着层级体系向上查找,直到找到数据或达到跟队列为止
-(void)demo3{      dispatch_queue_t queueA = dispatch_queue_create("com.lyk.queueA", NULL);      dispatch_queue_t queueB = dispatch_queue_create("com.lyk.queueB", NULL);      dispatch_set_target_queue(queueB, queueA);      static int kQueueSpecific;      CFStringRef queueSpecificValue = CFSTR("queueA");      dispatch_queue_set_specific(queueA, &kQueueSpecific, (voidvoid *)queueSpecificValue, (dispatch_function_t)CFRelease);      dispatch_sync(queueB, ^{          dispatch_block_t block = ^{              NSLog(@"NO deadlock!");          };          CFStringRef retrievedValue = dispatch_get_specific(&kQueueSpecific);          if (retrievedValue) {              block();          } else {              dispatch_sync(queueA, block);          }      });  }  
阅读全文
0 0
原创粉丝点击