1.GCD的簡介:程序員
Grand Central Dispatch 簡稱(GCD)是蘋果公司開發的技術,以優化的應用程序支持多核心處理器和其餘的對稱多處理系統的系統。這創建在任務並行執行的線程池模式的基礎上的。並且是純C語言,提供了很是多強大的函數。數據庫
2.GCD的工做原理是:網絡
讓程序平行排隊的特定任務,根據可用的處理資源,安排他們在任何可用的處理器核心上執行任務。一個任務能夠是一個函數(function)或者是一個block。 GCD的底層依然是用線程實現,不過這樣可讓程序員不用關注實現的細節。併發
3.GCD的優點:框架
GCD是蘋果公司爲多核的並行運算提出的解決方案;異步
GCD會自動利用更多的CPU內核(好比雙核、四核);async
GCD會自動管理線程的生命週期(建立線程、調度任務、銷燬線程);函數
程序員只須要告訴GCD想要執行什麼任務,不須要編寫任何線程管理代碼;優化
舒適提示:url
GCD存在於libdispatch.dylib這個庫中,這個調度庫包含了GCD的全部的東西,但任何IOS程序,默認就加載了這個庫,在程序運行的過程當中會動態的加載這個庫,不須要咱們手動導入。
4.GCD的使用步驟和核心概念:
核心機率有2個:1)隊列:用來存聽任務 2)任務:執行什麼操做
使用步驟有2步:1)定製任務 2)肯定想作的事情
5.dispatch queue(隊列):
GCD中的FIFO隊列稱爲dispatch queue,它能夠保證先進來的任務先獲得執行,dispatch queue分爲下面三種:
1)Serial dispatch queues(串行隊列),同時只執行一個任務(一個任務執行完畢之後,再執行下一個任務)。Serial queue一般用於同步訪問特定的資源或數據。當你建立多個Serial queue時,雖然它們各自是同步執行的,但Serial queue與Serial queue之間是併發執行的。
2)Concurren dispatch queue(併發隊列),能夠併發地執行多個任務(可讓多個任務同時執行,自動開啓多個線程同時執行任務,併發功能只有在異步函數(dispatch_async)下有效),可是執行完成的順序是隨機的。
3)Main dispatch queue(主隊列),它是全局可用的serial queue(直接在主線程中串行執行任務),它是在應用程序主線程上執行任務的。
6.GCD執行任務的兩種方式:
//將參數block(任務)提交給參數queue(隊列)進行執行,參數說明:queue:隊列 block:任務
(1)用同步的方式執行任務 dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
(2)用異步的方式執行任務 dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
7.爲了不界面在處理耗時的操做時卡死,好比讀取網絡數據,數據庫讀寫等,咱們會在另一個線程中處理這些操做,而後通知主線程更新界面。建立一個全局併發隊列,使用dispatch_async執行下載圖片任務,而後再回到主線程中展現圖片。
第一種方式---GCD結合NSThread
- (void)viewDidLoad { [super viewDidLoad]; imagev = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)]; [self.view addSubview:imagev]; //說明:全局併發隊列的優先級 #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默認(中) #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低 #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 後臺 //第一個參數全局併發隊列的優先級,第二個參數暫時無用,用0便可 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //使用異步的方式dispatch_async執行任務,第一個參數得到全局的併發隊列,第二個參數block(隊列將要執行的任務) dispatch_async(queue, ^{ //調用下載圖片方法 [self downImage]; }); }
-(void)downImage { //從網絡中下載圖片 NSURL *url = [NSURL URLWithString:@"http://i8.topit.me/8/c1/31/1142319854bdc31c18o.jpg"]; //將圖片轉換爲二進制數據 NSData *imgData = [NSData dataWithContentsOfURL:url]; //數據轉換成圖片 UIImage *img = [UIImage imageWithData:imgData]; //回到主線程設置圖片 [self performSelectorOnMainThread:@selector(senderImage:) withObject:img waitUntilDone:NO]; } -(void)senderImage:(UIImage *)image { imagev.image = image; }
第二種方式---GCD
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //從網絡中下載圖片 NSURL *url = [NSURL URLWithString:@"http://i8.topit.me/8/c1/31/1142319854bdc31c18o.jpg"]; //將圖片轉換爲二進制數據 NSData *imgData = [NSData dataWithContentsOfURL:url]; //數據轉換成圖片 UIImage *img = [UIImage imageWithData:imgData]; dispatch_async(dispatch_get_main_queue(), ^{ //回到主線程中設置圖片顯示 imagev.image = img; }); });
總結:系統給每個應用程序提供了三個concurrent dispatch queues。這三個併發調度隊列是全局的,它們只有優先級的不一樣。由於是全局的,咱們不須要去建立。咱們只須要經過使用函數dispath_get_global_queue去獲得隊列,以下:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
上面的例子中咱們也用到了,系統默認就有的一個串行隊列main_queue
dispatch_queue_t mainQueut = dispatch_get_main_queue();
他們的代碼框架結構以下:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //這裏就作一些比較耗時的操做,如請求數據。。 dispatch_async(dispatch_get_main_queue(), ^{ //這裏就是回到主線程去更新界面 }); });