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
相關文章
相關標籤/搜索