標籤「iOS」「多執行緒」「GCD」
GCD的簡單使用
什麼是GCD
- 全程是Grand Central Dispatch
- 純C語言,提供非常多強大的函式
- 多核並行運算,不叫多執行緒,它只是完成了多執行緒的封裝和使用
GCD的優勢
- GCD是蘋果公司為多核的並行運算提出的解決方案;
- iOS 4.0推出供開發者使用;
- 使用GCD不關心執行緒,只要關心佇列;執行緒的排程是由CPU排程,那麼我們的CPU是有多核的。如果開發者去排程執行緒,那是否要考慮CPU的核數了?開發者是不是要考慮適配? 而你使用GCD,則不用動,所以開發者很便利。這就是蘋果多它的CPU多核伏筆
- GCD 會自動利用更多的CPU核心(比如雙核、四核)
- GCD會自動管理執行緒的生命週期(建立執行緒、排程任務、銷燬執行緒)
- 程式設計師只需要告訴GCD想要執行什麼任務,不需要編寫任何執行緒管理程式碼
任務和佇列
GCD的2個核心概念
- 任務:執行什麼操作
- 佇列:用來存放任務
GCD的使用就2個步驟
- 定製任務(確定想做的事情) 將大象放進冰箱有幾步?
- 將任務新增到佇列中
GCD會自動將==佇列==中的==任務==取出,放到對應的==執行緒==中執行; 任務的取出遵循物件的==FIFO原則:先進先出,後進後出==
==畫圖分析== 程式設計師要做的,將任務新增到佇列;佇列按照程式設計師指定的方式,排程任務。執行任務的方法:同步/非同步 同步:一個任務沒有結束,就不會執行下一個任務 非同步:不用等待任務執行完畢,就會執行下一個任務
GCD有一個“執行緒池”;
- GCD同步排程任務時,會拿出1根執行緒,讓它執行佇列中的任務。當一個任務執行完成後,就會再從佇列一個一個的執行;
- GCD非同步排程任務時,首先拿出1根執行緒,讓這個執行緒去處理一個任務;當任務開始執行,就再從執行緒池裡,再獲取一個執行緒去佇列去順序拿任務執行;指定執行緒最大併發數;當其中的執行緒執行任務完畢後,再去佇列中按照FIFO原則獲取任務;
圖1:同步執行緒圖例
圖2:非同步執行緒圖例
==例項demo 001GCD程式碼演示==
在viewController 的touchBegain方法裡去呼叫方法。[self gcdDemo1]
- 在viewController裡,gcdDemo1方法:
1.建立佇列 2.新增任務到佇列中 3.將任務新增到佇列,並且會執行
寫block的方法的竅門:寫用函式的思路寫出,太函式名前面加一個括號()和 尖尖符號,再在函式體外面的大括號{}前面加一個尖尖符號。
/*
同步執行方法,這句話不執行完,就不會執行下個任務,同步執行不會開啟執行緒;
*/
-(void)gcdDemo1
{
//1.建立佇列
dispatch_queue_t q = dispatch_get_global_queue(0,0);
//2.任務新增到佇列中
//2.1定義任務--block
void (^task)() = ^{
NSLog(@"%@",[NSThread curresntThread]);
};
//2.2 新增任務到佇列,並且會執行
dispatch_sync(q,task);
//合併步驟1,2步,省略寫法
dispatch_sync(q,^{
NSLog(@"%@",[NSThread currentThread]);
});
}
複製程式碼
- 在viewController裡非同步執行任務,gcdDemo2方法:
1.建立佇列 2.新增任務到佇列中 3.將任務新增到非同步佇列,並且會執行
非同步執行,如果任務沒有執行完畢,可以不用等待;非同步執行下一個任務。具備開啟執行緒的能力,非同步通常又是多執行緒的代名詞!
/*
非同步任務
*/
-(void)gcdDemo2
{
//1.建立佇列
dispatch_queue_t q = dispatch_get_global_queue(0,0);
//2.1定義任務--block
void (^task)() = ^{
NSLog(@"%@",[NSThread curresntThread]);
};
//2.2 新增任務到佇列,並且會執行
dispatch_async(q,task);
}
複製程式碼
執行緒間的通訊
GCD之間的執行緒通訊
-(void)gcdDemo3
{
//指定任務執行方法 -- 非同步
dispatch_async(dispatch_get_global_queue(0,0),^{
//耗時操作
NSLog(@"%@",[NSThread currentThread]);
//更新UI
dispatch_async(dispatch_get_main_Queue(),^{
NSLog(@"更新UI%@",[NSThread currentThread]);
});
});
}
複製程式碼
==修改多執行緒demo 002--顯示網路圖片==
-(void)viewDidLoad
{
//程式碼集中,便於維護
//利用GCD獲取網路圖片
//非同步執行
dispatch_async(dispatch_get_global_queue(0,0),^{
NSURL *url = [NSURL URLWithString:@"http://img3.utuku.china.com/395x0/news/20170629/35381bbe-6e16-4be1-8cf4-4af9107448b7.jpg"];
NSData *data = [NSData dataWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
//更新UI
dispatch_async(dispatch_get_main_queue(),^{
self.imageView.image = image;
[self.imageView sizeToFit];
self.scrollView.contentSize = image.size;
});
//block沒有迴圈引用,只是一個程式碼塊,因為它沒有作為屬性,這裡的block用完就釋放了。
});
}
複製程式碼
讓一切儘可能簡單,但不是愚蠢。 —— 阿爾伯特·愛因斯坦
關注微信公眾號:iOSSir,每日更新蘋果資訊、技術乾貨!