這篇文章將演示GCD三個(gè)特性的使用:
1.延遲執(zhí)行
2.一次性執(zhí)行
3.調(diào)度組
- 延遲執(zhí)行
示例代碼:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"begin");
// 延遲執(zhí)行
/*
參數(shù)1: <#delayInSeconds#> --> 延遲多少時(shí)間執(zhí)行
參數(shù)2: dispatch_queue_t --> 執(zhí)行操作的隊(duì)列
參數(shù)3: dispatch_block_t --> 執(zhí)行的任務(wù)
異步執(zhí)行,并不會(huì)卡死主線程
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%s",__func__);
});
NSLog(@"end");
}
@end
LOG信息:
2016-08-21 13:39:05.720 延遲執(zhí)行[23451:3109328] begin
2016-08-21 13:39:05.721 延遲執(zhí)行[23451:3109328] end
2016-08-21 13:39:10.722 延遲執(zhí)行[23451:3109328] __41-[ViewController touchesBegan:withEvent:]_block_invoke
- 一次性執(zhí)行
示例代碼:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 一次性執(zhí)行 (線程安全,只執(zhí)行一次)
for (int i = 0; i < 10; i ++) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"%s",__func__);
});
}
}
@end
因?yàn)檫@種一次性執(zhí)行的特性,常常被使用在單例設(shè)計(jì)模式中,并且性能突出
http://www.itdecent.cn/p/1da234f4b551
- 調(diào)度組
有時(shí)候需要在多個(gè)異步任務(wù)都執(zhí)行完成之后繼續(xù)做某些事情,比如下載歌曲,等所有的歌曲都下載完畢之后,轉(zhuǎn)到主線程提示用戶,通過GCD的調(diào)度組功能即可實(shí)現(xiàn)這種需求
參數(shù)1:<#dispatch_group_t group#> -> 調(diào)度組
參數(shù)2:<#dispatch_queue_t queue#> -> 隊(duì)列
參數(shù)3:<#^(void)block#> -> 任務(wù)
dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
示例代碼:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
// 調(diào)度組使用
// 需求: 任務(wù)1&任務(wù)2&任務(wù)3 --> 全部都完成后(不限制執(zhí)行順序),提示完成
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
// 1.需要執(zhí)行的任務(wù)
dispatch_block_t task1 = ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"操作1");
};
dispatch_block_t task2 = ^{
[NSThread sleepForTimeInterval:5];
NSLog(@"操作2");
};
dispatch_block_t task3 = ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"操作3");
};
// 2.創(chuàng)建調(diào)度組
dispatch_group_t group = dispatch_group_create();
// 3.添加到調(diào)度組中
/* dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
參數(shù)1:<#dispatch_group_t group#> -> 調(diào)度組
參數(shù)2:<#dispatch_queue_t queue#> -> 隊(duì)列(處理任務(wù)執(zhí)行的隊(duì)列)
參數(shù)3:<#^(void)block#> -> 任務(wù)
*/
dispatch_group_async(group, dispatch_get_global_queue(0, 0), task1);
dispatch_group_async(group, dispatch_get_global_queue(0, 0), task2);
dispatch_group_async(group, dispatch_get_global_queue(0, 0), task3);
// 4.調(diào)度組內(nèi)的任務(wù)執(zhí)行完畢后回到主線程通知
/* dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)
參數(shù)1:<#dispatch_group_t group#> -> 調(diào)度組
參數(shù)2:<#dispatch_queue_t queue#> -> 隊(duì)列(參數(shù)3內(nèi)的代碼執(zhí)行隊(duì)列)
參數(shù)3:<#^(void)block#> -> 任務(wù)
*/
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"執(zhí)行完畢");
});
}
@end
上述調(diào)度組的示例代碼中,通過創(chuàng)建任務(wù),調(diào)度組,在通過調(diào)度組異步處理任務(wù)時(shí),將任務(wù)自動(dòng)放入調(diào)度組中執(zhí)行
調(diào)度組的原理:
- (void)demo{
// 創(chuàng)建調(diào)度組
dispatch_group_t group = dispatch_group_create();
// 相當(dāng)于任務(wù)1
// 將后面的代碼放入調(diào)度組中執(zhí)行
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"操作1");
//任務(wù)執(zhí)行完畢后離開調(diào)度組
dispatch_group_leave(group);
});
// 相當(dāng)于任務(wù)2
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:3];
dispatch_group_leave(group);
NSLog(@"操作2");
});
// 相當(dāng)于任務(wù)3
dispatch_group_enter(group);
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[NSThread sleepForTimeInterval:3];
NSLog(@"操作3");
dispatch_group_leave(group);
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"任務(wù)執(zhí)行完畢");
});
}
調(diào)度組的實(shí)現(xiàn)過程:
1.通過dispatch_group_enter(group);手動(dòng)讓后面的代碼進(jìn)入調(diào)度組
2.當(dāng)任務(wù)執(zhí)行完畢后,通過dispatch_group_leave(group);離開調(diào)度組
3.當(dāng)所有任務(wù)執(zhí)行完畢后,調(diào)用dispatch_group_notify做最后的處理
dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, <#^(void)block#>)