GCD
1、Grand Central Dispatch是由蘋果開發的一個多核程式設計的解決方案,自動管理現成的生命周期(建立線程、排程任務、銷毀線程)。
2、主要包括任務(執行什麼操作)和隊列(用來存放任務)。
3、同步方式(目前線程)
異步方式(開一條線程)
4、并發隊列:可以讓多個任務同時執行,隻有在異步方式下才有效
串行隊列:任務一個接一個執行
總結:同步異步決定能不能開啟線程,并發串行決定是多個任務同時執行還是一個一個執行
5、GCD中有三種隊列類型:
- The main queue: 與主線程功能相同。實際上,送出至main queue的任務會在主線程中執行。main queue可以調用dispatch_get_main_queue()來獲得。因為main queue是與主線程相關的,是以這是一個串行隊列。
- Global queues: 全局隊列是并發隊列,并由整個程序共享。程序中存在三個全局隊列:高、中(預設)、低三個優先級隊列。可以調用dispatch_get_global_queue函數傳入優先級來通路隊列。
- 使用者隊列: 使用者隊列 (GCD并不這樣稱呼這種隊列, 但是沒有一個特定的名字來形容這種隊列,是以我們稱其為使用者隊列) 是用函數
建立的隊列. 這些隊列是串行的。dispatch_queue_create
6、隊列的使用
1.全局并行隊列異步執行
/**
* async -- 并發隊列(最常用)
* 會不會建立線程:會,一般同時開多條
* 任務的執行方式:并發執行
*/
- (void)asyncGlobalQueue
{
// 獲得全局的并發隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 将 任務 添加 全局隊列 中去 異步 執行
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔5---%@", [NSThread currentThread]);
});
}
2.串行隊列異步執行
/**
* async -- 串行隊列(有時候用)
* 會不會建立線程:會,一般隻開1條線程
* 任務的執行方式:串行執行(一個任務執行完畢後再執行下一個任務)
*/
- (void)asyncSerialQueue
{
// 1.建立一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);
// 2.将任務添加到串行隊列中 異步 執行
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔5---%@", [NSThread currentThread]);
});
// 3.非ARC,需要釋放建立的隊列
// dispatch_release(queue);
}
3.主隊列異步執行
/**
* async -- 主隊列(很常用)
*/
- (void)asyncMainQueue
{
// 1.主隊列(添加到主隊列中的任務,都會自動放到主線程中去執行)
dispatch_queue_t queue = dispatch_get_main_queue();
// 2.添加 任務 到主隊列中 異步 執行
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔1---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔2---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔3---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔4---%@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"-----下載下傳圖檔5---%@", [NSThread currentThread]);
});
}
4.全局并發隊列同步執行
/**
* sync -- 并發隊列
* 會不會建立線程:不會
* 任務的執行方式:串行執行(一個任務執行完畢後再執行下一個任務)
* 并發隊列失去了并發的功能
*/
- (void)syncGlobalQueue
{
// 獲得全局的并發隊列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 将 任務 添加到 全局并發隊列 中 同步 執行
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔5---%@", [NSThread currentThread]);
});
}
5.串行隊列同步執行
/**
* sync -- 串行隊列
* 會不會建立線程:不會
* 任務的執行方式:串行執行(一個任務執行完畢後再執行下一個任務)
*/
- (void)syncSerialQueue
{
// 建立一個串行隊列
dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL);
// 将 任務 添加到 串行隊列 中 同步 執行
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔1---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔2---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔3---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔4---%@", [NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"-----下載下傳圖檔5---%@", [NSThread currentThread]);
});
}
7、線程間通信(最常用)
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"donwload---%@", [NSThread currentThread]);
// 1.子線程下載下傳圖檔
NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
// 2.回到主線程設定圖檔
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"setting---%@ %@", [NSThread currentThread], image);
[self.button setImage:image forState:UIControlStateNormal];
});
});
8、延遲執行
// 3秒後回到主線程執行block中的代碼
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
NSLog(@"------task------%@", [NSThread currentThread]);
});
// 3秒後自動開啟新線程 執行block中的代碼
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
NSLog(@"------task------%@", [NSThread currentThread]);
});
// 一旦定制好延遲任務後,不會卡主目前線程
[self performSelector:@selector(download:) withObject:@"http://555.jpg" afterDelay:3];
9、一次性代碼
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"----once");
HMImageDownloader *downloader = [[HMImageDownloader alloc] init];
[downloader download];
});