今天風超大的,把我人都快吹走了,但是我還是回來來。。。啦啦啦,長話短說,下面為大家准備了GCD的深入了解。大家可以復制到自己的Xcode裡面運行下了。然後仔細看看這些介紹,多敲幾遍。其實很簡單的,一個並發 一個串行隊列。。。就像我們走路一樣,3個人走一排角並發 ,把3個人拍好隊一個個走,就是串行隊列。。哈哈,是不是很有意思呢?
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//------------------ GCD ---------------------
//1.什麼是GCD?
//Grand Central Dispatch (大中央調度),純C語言,提供了非常多強大的函數
//2. GCD的優勢
//2.1 GCD是蘋果公司為多核的並行運算提出的解決方法
//2.2 GCD會自動利用更多地CPU內核(雙核,四核)
//2.3 GCD會自動管理線程的生命周期(包括,創建線程,調度任務,銷毀線程)
//2.4 程序員只需要告訴GCD想要執行什麼任務,不需要編寫任何線程管理代碼
// ----------------任務和隊列-------------------------
//GCD中又兩個核心概念
// 1. 任務 :執行什麼操作
// 2. 隊列 :用來存放任務
//GCD的使用就兩個步驟
// 1. 定制隊列
// 2. 確定想做的事情
//將任務添加到隊列中,GCD會自動將隊列中的任務取出,放到對應的線程中執行,任務的取出遵循隊列的FIFO原則:先進先出,後進後出
// ------------ 執行任務----------------
//1.GCD中有兩個用來執行任務的函數
//說明: 把右邊的參數(任務)提交給左邊的參數(隊列)中執行
//(1) 用同步的方式執行任務 dispatch_sync(dispatch_queue_t queue, <#^(void)block#>)
//(2) 用異步的方式執行任務dispatch_async(dispatch_queue_t queue, <#^(void)block#>)
//2. 同步和異步的區別
//同步: 在當前線程中執行
//異步: 在另一條線程中執行
// ------------- 隊列 -----------------------
// 1. 隊列的類型
//1.1 並發隊列 (Concurrent Dispatch Queue)可以讓多個任務並發執行(自動開啟多個線程同時執行任務),並發功能只由在異步函數(dispatch_async)下才有效
//1.2 串行隊列 (Serial Dispatch Queue) 讓任務一個接著一個執行
// 同步,異步,並發,串行
// 同步和異步決定了要不要開啟新線程
// 同步: 在當前線程中執行任務,不具備開啟新線程的能力
// 異步: 在新德線程中執行任務,具備開啟新線程的能力
// 並發和串行決定了任務的執行方式
// 並發: 多個任務並發執行
// 串行: 一個任務執行完畢後,再執行下一個任務
//-------------------- 串行隊列 -------------------
//GCD中獲取串行隊列有兩種方法
//1. dispatch_queue_create(<#const char *label#>, <#dispatch_queue_attr_t attr#>) //隊列名稱, 隊列屬性,一般為NULL
//2. dispatch_queue_t queue = dispatch_get_main_queue(),取到主隊列, 主隊列是GCD自帶的一種特殊隊列, 放在主隊列中得任務,都會放到主線程中執行。
// ----------------- 並發隊列 -------------------
// GCD默認已經提供了全局的並發隊列, 供整個應用使用,不需要手動創建
// dispatch_queue_t queue = dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>) 第一個參數為優先級, 第二個參數為保留參數,給以後使用的,傳0即可。
// ------------ 總結 --------------------
// 同步函數不具備開啟線程的能力, 無論什麼隊列都不會開啟線程。
// 異步函數具備開啟線程的能力, 開啟幾條線程由隊列決定(串行隊列只會開啟一條新德線程,並發隊列會開啟多條線程)
// ----------- 補充 --------------------
//凡是函數中,各種函數名中帶有create\copy\new\retain等字眼,都需要在不需要使用這個數據的時候進行release。
//GCD的數據類型在ARC的環境下不需要再做release。
//CF(core Foundation)的數據類型在ARC環境下還是需要做release。
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
//[self test1];
// [self test2];
// [self test3];
[self test4];
}
// 在同步函數中的串行隊列中添加任務, 不會開辟新線程
-(void)test1
{
//1. 創建串行隊列 _t _ref C語言的數據類型
// 參數1 : 隊列的名稱
// 參數2 : 隊列的屬性 一般填NULL,表示創建串行隊列,
// 參數2 中填 DISPATCH_QUEUE_SERIAL 創建串行隊列
// DISPATCH_QUEUE_CONCURRENT 創建並行隊列
dispatch_queue_t queue = dispatch_queue_create("Serial Queue", NULL);
dispatch_sync(queue, ^{
NSLog(@"下載任務1,curThread = %@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
});//在這,要等到任務執行完成才會接到執行
NSLog(@"111");
dispatch_sync(queue, ^{
NSLog(@"下載任務2,curThread = %@",[NSThread currentThread]);
});
NSLog(@"222");
dispatch_sync(queue, ^{
NSLog(@"下載圖片任務3,currThread = %@",[NSThread currentThread]);
});
NSLog(@"333");
}
//在同步函數中的並行隊列中添加任務, 不會開辟新線程,並發的功能無效
-(void)test2
{
//1. 取到並行隊列,在iOS中,系統為每一個應用程序已經准備了一天全局隊列,該全局隊列為並行隊列。
// 參數1 : 隊列的優先級, 一般取默認優先級
// 參數2 : 保留參數,填0
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_sync(queue, ^{
NSLog(@"下載圖片任務1, curThread = %@",[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
});
NSLog(@"111");
dispatch_sync(queue, ^{
NSLog(@"下載圖片任務2,curThread = %@",[NSThread currentThread]);
});
NSLog(@"222");
dispatch_sync(queue, ^{
NSLog(@"下載圖片任務3,curThread = %@",[NSThread currentThread]);
});
NSLog(@"333");
}
/**
* 在異步函數中的串行隊列中添加任務, 會開辟新線程,但是只會開辟一個線程。
*/
- (void)test3
{
// 1. 創建串行隊列
dispatch_queue_t queue = dispatch_queue_create("Serial Queue", DISPATCH_QUEUE_SERIAL);
//2. 通過異步函數在串行隊列中添加任務
dispatch_async(queue, ^{
NSLog(@"下載圖片任務1 , curThread = %@",
[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
});
NSLog(@"1111");
dispatch_async(queue, ^{
NSLog(@"下載圖片任務2 , curThread = %@",
[NSThread currentThread]);
});
NSLog(@"2222");
dispatch_async(queue, ^{
NSLog(@"下載圖片任務3 , curThread = %@",
[NSThread currentThread]);
[NSThread sleepForTimeInterval:2];
});
NSLog(@"333");
}
/**
* 在異步函數中的並行隊列中添加任務, 可能會開辟多個新線程
*/
- (void)test4
{
//1 .創建並行隊列
dispatch_queue_t queue = dispatch_queue_create("Concurrent Queue", DISPATCH_QUEUE_CONCURRENT);
//2. 通過異步函數在並行隊列中添加任務
dispatch_async(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"下載圖片任務1 , curThread = %@",
[NSThread currentThread]);
});
NSLog(@"1111");
dispatch_async(queue, ^{
NSLog(@"下載圖片任務2 , curThread = %@",
[NSThread currentThread]);
});
NSLog(@"2222");
dispatch_async(queue, ^{
NSLog(@"下載圖片任務3 , curThread = %@",
[NSThread currentThread]);
// [NSThread sleepForTimeInterval:2];
});
NSLog(@"333");
}
@end