iosGCD的簡單介紹2
今天風超大的,把我人都快吹走了,但是我還是回來來。。。啦啦啦,長話短說,下面為大家準備了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