標籤:blog ar io os sp for on 2014 log
(1)GCD實現的同步非同步、串列並行。
——同步sync應用情境:使用者登入,利用阻塞
——串列非同步應用情境:下載等耗時間的任務
/** * 因為是非同步,所以開通了子線程,但是因為是串列隊列,所以只需要開通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實現的線程管理
/** * 1、只要是自己建立的隊列,添加進來的操作(此處是block操作),都在子線程上(2) * 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
【iOS開發-91】GCD的同步非同步串列並行、NSOperation和NSOperationQueue一級用dispatch_once實現單例