轉: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