
u=1546308334,1185521960&fm=21&gp=0.jpg
GCD
簡(jiǎn)介
- 1.旨在代替NSThread等線程技術(shù)
- 2.能夠充分利用多核的特點(diǎn)
- 3.用到的兩個(gè)核心概念:隊(duì)列(并發(fā)+串行)+任務(wù)(同步+異步)
- 有一點(diǎn)需要注意:異步函數(shù)具有開啟線程的能力,而同步函數(shù)不會(huì)開啟線程
基本使用
- 01 異步函數(shù)+并發(fā)隊(duì)列:開啟多條線程,并發(fā)執(zhí)行任務(wù)(最常用)
- 02 異步函數(shù)+串行隊(duì)列:開啟一條線程,串行執(zhí)行任務(wù)
- 03 同步函數(shù)+并發(fā)隊(duì)列:不開線程,在當(dāng)前線程里串行執(zhí)行任務(wù)
- 04 同步函數(shù)+串行隊(duì)列:不開線程,在當(dāng)前線程里串行執(zhí)行任務(wù)
- 05 異步函數(shù)+主隊(duì)列:不開線程,在主線程中串行執(zhí)行任務(wù)
- 06 同步函數(shù)+主隊(duì)列:不開線程,串行執(zhí)行任務(wù)(注意死鎖發(fā)生)
常用代碼示例:
- 1.異步+并發(fā)
//異步+并發(fā)(創(chuàng)建多個(gè)線程,并發(fā)執(zhí)行)
-(void)asyncConcurrent{
/*
第一個(gè)參數(shù):C語(yǔ)言的字符串 給隊(duì)列起一個(gè)名字
第二個(gè)參數(shù):類型
DISPATCH_QUEUE_CONCURRENT 并發(fā)隊(duì)列
DISPATCH_QUEUE_SERIAL 串行隊(duì)列
*/
//創(chuàng)建并發(fā)隊(duì)列
dispatch_queue_t queue=dispatch_queue_create("wujian.com.con", DISPATCH_QUEUE_CONCURRENT);
//封裝任務(wù)并把任務(wù)添加到隊(duì)列當(dāng)中
dispatch_async(queue, ^{
NSLog(@"1--------------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2--------------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3--------------%@",[NSThread currentThread]);
});
}
- 2.異步+串行
-(void)asyncSerial{
NSLog(@"開始---");
dispatch_queue_t queue=dispatch_queue_create("lslslslsll.com", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"1--------------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2--------------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3--------------%@",[NSThread currentThread]);
});
NSLog(@"結(jié)束---");
}
注意:此處運(yùn)行會(huì)發(fā)現(xiàn)先打印“開始--”,然后打印“結(jié)束--”,在這之后再處理這兩者中間的具體任務(wù),這其實(shí)是異步函數(shù)的一個(gè)特點(diǎn),異步函數(shù)采用的是回調(diào)的機(jī)制,像打印這種簡(jiǎn)單的操作,就直接執(zhí)行了,而對(duì)于異步函數(shù)里的任務(wù),在其他操作完成之后再去執(zhí)行,這樣做會(huì)防止死鎖的發(fā)生。
- 3.同步+串行(在當(dāng)前線程中串行執(zhí)行)
-(void)syncSerial{
dispatch_queue_t queue=dispatch_queue_create("com.sssss", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{
NSLog(@"1--------------%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2--------------%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3--------------%@",[NSThread currentThread]);
});
}
- 4.同步+并發(fā)(不會(huì)創(chuàng)建線程,在當(dāng)前線程中串行執(zhí)行)
-(void)syncConcurrent{
//自己創(chuàng)建的并發(fā)隊(duì)列
// dispatch_queue_t queue=dispatch_queue_create("ldsjfl.com", DISPATCH_QUEUE_CONCURRENT);
//獲取全局隊(duì)列(用法與上面幾乎無異)
dispatch_queue_t queue=dispatch_get_global_queue(0, 0);
dispatch_sync(queue, ^{
NSLog(@"1--------------%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2--------------%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3--------------%@",[NSThread currentThread]);
});
}
- 5.異步+主隊(duì)列(與主線程相關(guān)):在主線程中串行執(zhí)行,由于異步的執(zhí)行特點(diǎn),所以不會(huì)造成死鎖
-(void)asyncMainQueue{
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"1--------------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2--------------%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3--------------%@",[NSThread currentThread]);
});
}
- 6.同步+主隊(duì)列:會(huì)造成死鎖(在子線程中不會(huì)有死鎖發(fā)生)
- 如果主隊(duì)列中有任務(wù),那么主隊(duì)列會(huì)安排主線程來執(zhí)行當(dāng)前隊(duì)列中的任務(wù),但是在調(diào)度之前會(huì)先檢查主線程的狀態(tài),如果主線程在忙那么就暫停調(diào)度隊(duì)列中的任務(wù),等到主線程空閑的時(shí)候再調(diào)度(而此處的主線程剛好在執(zhí)行自身這個(gè)函數(shù)) (只有主隊(duì)列關(guān)心主線程忙不忙)
-(void)syncMainQueue{
NSLog(@"ssss");
dispatch_queue_t queue=dispatch_get_main_queue();
dispatch_sync(queue, ^{
NSLog(@"1--------------%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2--------------%@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3--------------%@",[NSThread currentThread]);
});
}
獲得串行隊(duì)列的兩種途徑
- 1.通過函數(shù)自己創(chuàng)建
dispatch_queue_t queue=dispatch_queue_create("lslslslsll.com", DISPATCH_QUEUE_SERIAL);
- 2.獲得系統(tǒng)的主隊(duì)列
dispatch_queue_t queue=dispatch_get_main_queue();
獲得全局隊(duì)列的兩種途徑
- 1.通過函數(shù)自己創(chuàng)建
dispatch_queue_t queue=dispatch_queue_create("wujian.com.con", DISPATCH_QUEUE_CONCURRENT);
- 2.獲得系統(tǒng)的全局隊(duì)列(建議使用這種方法)
//第一個(gè)參數(shù)是隊(duì)列的優(yōu)先級(jí),可以傳0表示默認(rèn),第二個(gè)參數(shù)暫時(shí)用不上,是蘋果預(yù)留的參數(shù),傳0即可。
dispatch_queue_t queue=dispatch_get_global_queue(0, 0);
GCD中的線程通信
- (void)viewDidLoad {
[super viewDidLoad];
//開子線程
//01 獲得全局并發(fā)隊(duì)列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//02 使用異步函數(shù)+并發(fā)隊(duì)列
dispatch_async(queue, ^{
//03 確定URL
NSURL *url = [NSURL URLWithString:@"http://XXXXX.jpg"];
//04 把圖片的二進(jìn)制數(shù)據(jù)下載到本地
NSData *data = [NSData dataWithContentsOfURL:url];
//05 轉(zhuǎn)換格式
UIImage *image = [UIImage imageWithData:data];
NSLog(@"耗時(shí)操作---%@",[NSThread currentThread]);
//06 顯示圖片(回到主線程,其實(shí)是一種嵌套的模式)
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
NSLog(@"UI操作---%@",[NSThread currentThread]);
});
});
}