ios有三種多線程編程技術,分別是NSThread,Cocoa NSOperation和GCD,GCD全稱Grand Central Dispatch 是Apple開發的一個多核編程的解決方法,在iOS4.0開始之后才能使用。GCD是一個可以替代NSThread, NSOperationQueue, NSInvocationOperation等技術的很高效和強大的技術,而且其使用起來比前兩者更加的簡單方便,今天主要給大家介紹一下有關GCD的使用。
GCD的工作原理是:讓程序平行排隊的特定任務,根據可用的處理資源,安排他們在任何可用的處理器核心上執行任務。一個任務可以是一個函數或者是一個語句塊(block),GCD的依然是用線程實現,不過這樣可以讓普通開發者不用去關注其實現的細節,GCD中的隊列稱為dispatch queue。
Dispatch Queue分為三種:
1. Serial Dispatch Queue: 線性執行的線程隊列,遵循FIFO(First In First Out)原則;
2. Concurrent Dispatch Queue: 并發執行的線程隊列,并發執行的處理數取決于當前狀態;
3. Main Dispatch Queue:在應用程序主線程上執行任務。
先來看幾個常用的方法:
1.dispatch_async
有的時候避免界面在處理耗時的操作時卡死,比如發起網絡請求,下載數據,緩存圖片等,我們需要在另外的一個線程中處理這些操作,在這些操作完成后再通知主線程更新界面,看下面一段代碼
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //耗時操作 NSDate* date = [NSDate date]; NSLog(@"------%@",date); NSURL * url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/0823dd54564e9258ca2f34e79e82d158ccbf4e9b.jpg"]; NSData * data = [[NSData alloc]initWithContentsOfURL:url]; UIImage *image = [[UIImage alloc]initWithData:data]; [NSThread sleepForTimeInterval:4];//為了體現多線程的特點 在這里設置一個延時 if (data != nil) { dispatch_async(dispatch_get_main_queue(), ^{ //結果處理 UIImageView* imageview = [[UIImageView alloc]initWithImage:image]; imageview.frame = [UIScreen mainScreen].bounds; [self.view addSubview:imageview]; NSDate* date = [NSDate date]; NSLog(@"------%@",date); }); } });
我們在一個線程里完成下載圖片的動作(為了體現多線程的作用,我們在這里設置一個延時)然后在另一個線程里把圖片顯示出來,來看一下運行結果。
系統給每個應用都提供的有隊列,所以一般不用我們手動的去創建,我們只需要通過函數去獲取隊列就可以了
// 獲取Main Dispatch Queuedispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();// 獲取Global Dispatch Queuedispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_async可以實現一組任務的監聽,在一系列任務完成后再進行其他的操作。
看一段例子:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"線程1"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:5]; NSLog(@"線程2"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:3]; NSLog(@"線程3"); });
//dispatch_group_notify函數用來指定一個額外的block,該block將在group中所有任務完成后執行 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"更新操作"); });
由結果可以看出,3個線程都執行完成后,更新操作才執行
dispatch_barrier_async是在前面的任務執行結束后才執行,而且它后面的任務等它執行完成之后才會執行
dispatch_queue_t queue = dispatch_queue_create("gcdtest2", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"線程1"); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:5]; NSLog(@"線程2"); }); dispatch_barrier_async(queue, ^{ NSLog(@"barrier執行"); [NSThread sleepForTimeInterval:5]; }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"線程4"); });
新聞熱點
疑難解答