GCD的同步异步串行并行、NSOperation和NSOperationQueue一级用dispatch_once实现单例

转:http://www.tuicool.com/articles/NVVnMnjava

(1)GCD实现的同步异步、串行并行。异步

——同步sync应用场景:用户登陆,利用阻塞async

——串行异步应用场景:下载等耗时间的任务ui

/**
 *  由于是异步,因此开通了子线程,可是由于是串行队列,因此只须要开通1个子线程(2),它们在子线程中顺序执行。最经常使用。
 */
-(void)gcdDemo1{  dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL);  for (int i=0; i<10; i++) {   dispatch_async(q1, ^{    NSLog(@"%@",[NSThread currentThread]);   });  } } /** * 由于是异步,因此开通了子线程,且由于是并行队列,因此开通了好多个子线程,具体几个,无人知晓,看运气。线程数量没法控制,且浪费。 */ -(void)gcdDemo2{  dispatch_queue_t q2=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_CONCURRENT);  for (int i=0; i<10; i++) {   dispatch_async(q2, ^{    NSLog(@"%@",[NSThread currentThread]);   });  } } /** * 由于是同步,因此不管是并行队列仍是串行队列,都是在主线程中执行 */ -(void)gcdDemo3{  dispatch_queue_t q1=dispatch_queue_create("com.hellocation.gcdDemo", DISPATCH_QUEUE_SERIAL);  for (int i=0; i<10; i++) {   dispatch_sync(q1, ^{    NSLog(@"%@",[NSThread currentThread]);   });  } } /** * 全局队列和并行队列相似(全局队列不须要建立直接get便可,而致使其没有名字,不利于后续调试) */ -(void)gcdDemo5{  dispatch_queue_t q=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);  for (int i=0; i<10; i++) {   dispatch_sync(q, ^{    NSLog(@"%@",[NSThread currentThread]);   });  }  for (int i=0; i<10; i++) {   dispatch_async(q, ^{    NSLog(@"%@",[NSThread currentThread]);   });  } } /** * 由于是主线程,因此异步任务也会在主线程上运行(1)。而若是是同步任务,则阻塞了,由于主线程一直会在运行,因此后米的任务永远不会被执行。 * 主要用处,是更新UI,更新UI一概在主线程上实现 */ -(void)gcdDemo6{  dispatch_queue_t q=dispatch_get_main_queue();  for (int i=0; i<10; i++) {   dispatch_sync(q, ^{    NSLog(@"%@",[NSThread currentThread]);   });  } // for (int i=0; i<10; i++) { // dispatch_async(q, ^{ // NSLog(@"%@",[NSThread currentThread]); // }); // } } 

(2)NSOperation和NSOperationQueue实现的线程管理spa

/**
 *  一、只要是本身建立的队列,添加进来的操做(此处是block操做),都在子线程上(2)
 *  二、只要是在主队列中,添加进来的操做,都在主线程上(1)
 *  两个队列不能同时抢一个任务操做
 */
-(void)opDemo1{  NSOperationQueue *queue=[[NSOperationQueue alloc]init];  NSBlockOperation *b=[NSBlockOperation blockOperationWithBlock:^{   NSLog(@"%@",[NSThread currentThread]);  }];  [queue addOperation:b];  [[NSOperationQueue mainQueue]addOperation:b]; } /** * 同上 */ -(void)opDemo2{  NSInvocationOperation *i=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(helloWorld) object:nil];  NSOperationQueue *queue=[[NSOperationQueue alloc]init];  [queue addOperation:i];  [[NSOperationQueue mainQueue]addOperation:i]; } -(void)helloWorld{  NSLog(@"hello,world!"); } /** * 依赖关系:(1)能够保证执行顺序,也使得开的子线程不会太多;(2)能够跨队列,而串行是不能够跨队列的,如最后更新UI则变成在主队列中。 * 这是NSOperation(NSBlockOperation和NSInvocationOperation)和NSOperationQueue的优点 */ -(void)opDemo3{  NSBlockOperation *op1=[NSBlockOperation blockOperationWithBlock:^{   NSLog(@"下载图片 %@",[NSThread currentThread]);  }];  NSBlockOperation *op2=[NSBlockOperation blockOperationWithBlock:^{   NSLog(@"修饰图片 %@",[NSThread currentThread]);  }];  NSBlockOperation *op3=[NSBlockOperation blockOperationWithBlock:^{   NSLog(@"保存图片 %@",[NSThread currentThread]);  }];  NSBlockOperation *op4=[NSBlockOperation blockOperationWithBlock:^{   NSLog(@"更新UI %@",[NSThread currentThread]);  }];  [op4 addDependency:op3];  [op3 addDependency:op2];  [op2 addDependency:op1];  NSOperationQueue *queue=[[NSOperationQueue alloc]init];  //设置同一时刻最大开启的线程数,这是NSOperationQueue特有的  [queue setMaxConcurrentOperationCount:2];  [queue addOperation:op1];  [queue addOperation:op2];  [queue addOperation:op3];  [[NSOperationQueue mainQueue]addOperation:op4]; } 

(3)单例的实现(手写单例要求)dispatch_once运用,即重写类的allocWithZone方法线程

@implementation WPObject
+(instancetype)allocWithZone:(struct _NSZone *)zone{
 static WPObject *insta;  static dispatch_once_t onceToken;  dispatch_once(&onceToken, ^{   insta=[super allocWithZone:zone];  });  return insta; } @end