本篇文章中我們主要講解GCD中的函數衣赶。
GCD
GCD
是Grand Central Dispatch
的簡稱伍茄,純c語言
淹朋,提供了非常多強大的函數,將任務添加到隊列荠卷,并且指定執(zhí)行任務的函數
模庐。
函數
- 1,
GCD中的函數
使用block
封裝油宜,任務的block沒有參數也沒有返回值掂碱。 - 2,異步函數
dispatch_async
: 不用等待當前語句執(zhí)行完畢慎冤,就可以執(zhí)行下一條語句疼燥,會開啟線程執(zhí)行block的任務。 - 3蚁堤,同步函數
dispatch_sync
醉者,必須等待當前語句執(zhí)行完畢,才會執(zhí)行下一條語句披诗,不會開啟線程
撬即,在當前執(zhí)行block的任務。
函數與隊列
同步函數串行隊列
- 1呈队,
不會開啟線程
剥槐,在當前線程執(zhí)行任務。 - 2宪摧,任務串行執(zhí)行粒竖,任務一個接著一個。
- 3几于,會產生堵塞蕊苗。
同步函數并發(fā)隊列
- 1,
不會開啟線程
沿彭,在當前線程執(zhí)行任務朽砰。 - 2,任務一個接著一個執(zhí)行。
異步函數串行隊列
- 1锅移,
開啟一條新線程
熔掺。 - 2,任務一個接著一個執(zhí)行非剃。
異步函數并發(fā)對列
- 1,
開啟線程
推沸,在當前線程執(zhí)行任務备绽。 - 2,
任務異步執(zhí)行鬓催,沒有順序
肺素,與CPU調度有關。
dispatch_sync
dispatch_sync
函數宇驾,如果 dispatch_sync()
的目標queue
為當前queue
倍靡,且 當前queue為串行隊列
時,會發(fā)生死鎖
(并行queue并不會)课舍。
下面我們通過下面的幾個函數示例來驗證一下:
- (void)viewDidLoad {
[super viewDidLoad];
[self mainSyncTest];
}
- (void)mainSyncTest{
NSLog(@"0");
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"1");
});
NSLog(@"2");
}
- 在
主線程
中調用dispatch_sync
函數塌西,且目標queue
,為主線程
藕坯,住線程是一個串行隊列
肺缕,所以會造成死鎖
掩蛤。
- (void)test1{
dispatch_queue_t queue = dispatch_queue_create("LY", NULL);
NSLog(@"1");
// 異步函數
dispatch_async(queue, ^{
NSLog(@"2");
// 同步
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- (void)test2 {
dispatch_queue_t queue1 = dispatch_queue_create("LY", NULL); // 串行隊列
dispatch_queue_t queue2 = dispatch_queue_create("Nice", NULL); // 串行隊列
NSLog(@"1");
// 異步函數
dispatch_async(queue1, ^{
NSLog(@"2");
// 同步
dispatch_sync(queue2, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- test1 函數亲善,
目標queue
是當前queue
冗疮,并且都為串行隊列喷斋,會導致死鎖
培漏。 - test2 函數兑巾,
dispatch_sync
的當前queue
為queue1
损姜,目標queue
為queue2
饰剥,因為queue1和queue2
不是同一個隊列,不會造成死鎖摧阅。
-(void) test3 {
dispatch_queue_t queue = dispatch_queue_create("LY", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"1");
dispatch_async(queue, ^{
NSLog(@"2");
dispatch_sync(queue, ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
- test3 函數汰蓉,
dispatch_sync
函數的當前queue
和目標queue
為同一個queue
。但該隊列為并發(fā)隊列
逸尖,并不會造成死鎖古沥。
最后,奉上本文的代碼示例 GCD