多线程有好多实现方式,我先掌握一种就行了。
GCD并非想象中的那么难,只是不敢尝试,不知道应用在何处。
今天看了慕课上‘不死鸟fj’讲解的GCD,才算了解了一些基本运用。
下面我总结一下我的学习成果。(我会使用 [NSThread sleepForTimeInterval:3]模拟耗时操作)
1.最简单的使用
- (void)onGCD:(UIButton *)btn{
NSLog(@"执行GCD");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"执行耗时任务");
[NSThread sleepForTimeInterval:3];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主线程,刷新UI");
[btn setTitle:@"ok" forState:UIControlStateNormal];
});
});
}
2.并发(也就是多几个耗时操作一同进行,相当于你做饭的时候听着歌,两不耽误)
DISPATCH_QUEUE_PRIORITY_LOW,DISPATCH_QUEUE_PRIORITY_DEFAULT,DISPATCH_QUEUE_PRIORITY_HIGH参数代表优先级别由低—>高
//并发
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSLog(@"start task 1");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 1");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"start task 2");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 2");
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
NSLog(@"start task 3");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 3");
});
3.并行/串行
参数:
DISPATCH_QUEUE_CONCURRENT--并行
DISPATCH_QUEUE_SERIAL--串行(保证执行顺序,好比接力,1棒跑完,2棒才能跑,适用于任务2必须在任务1完成的情况下才能继续运行)
//并行
dispatch_queue_t quene = dispatch_queue_create("com.task", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(quene, ^{
NSLog(@"start task 1");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 1");
});
dispatch_async(quene, ^{
NSLog(@"start task 2");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 2");
});
dispatch_async(quene, ^{
NSLog(@"start task 3");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 3");
});
4.所有任务完成之后执行下一步(适用场景:多个网络请求完成之后刷新界面)
参数:
"com.task.gcd":唯一标识
DISPATCH_QUEUE_CONCURRENT/DISPATCH_QUEUE_SERIAL:并行/串行
- (void)onGCD:(UIButton *)btn{
dispatch_queue_t queue = dispatch_queue_create("com.task.gcd", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
dispatch_group_enter(group);
[self requestInfo1:^{
NSLog(@"request1 done");
dispatch_group_leave(group);
}];
dispatch_group_enter(group);
[self requestInfo2:^{
NSLog(@"request2 done");
dispatch_group_leave(group);
}];
dispatch_group_notify(group, queue, ^{
NSLog(@"全部执行完毕");
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"回到主线程,刷新UI");
});
});
}
- (void)requestInfo1:(void(^)())blok{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"start task 1");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 1");
dispatch_async(dispatch_get_main_queue(), ^{
if (blok) {
blok();
}
});
});
}
- (void)requestInfo2:(void(^)())blok{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"start task 2");
[NSThread sleepForTimeInterval:3];
NSLog(@"start task 2");
dispatch_async(dispatch_get_main_queue(), ^{
if (blok) {
blok();
}
});
});
}
5.GCD的其他应用,让代码只运行一次
- (void)onClick:(UIButton *)btn{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"我只响应一次");
});
}