前段时间在研究了一些比较耗性能的东西,发现多线程的重要性,于是整理了一下关于GCD应用方面的东西,直接copy了整个.m 文件。算是一些基本概念。以后有用到的时候可以方便来查看。
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
#pragma mark - 基本概念
//1.两个核心的概念
//任务:想要做的事情(需要执行的操作)
//队列:存放任务的容器(特点是先进先出)
//2.四大名词
//(1)任务的执行方式(决定了能不能开启新的线程)
//同步:任务在当前线程中执行(不具备开启新线程的能力)--- 任务需要马上执行
//异步:任务在其他线程中执行(具备开启新线程的能力)--- 任务可以等当前函数结束后再执行
//(2)队列的类型
//并发:多个任务可以同时执行(前提是有多个线程)
//串行:队列中任务按顺序一个一个执行;必须是一个执行完,再执行下一个
//3.使用步骤
//(1)创建队列
//(2)将指定的任务放到创建好的队列中。(将任务放到队列中后,GCD会自动将队列中的任务取出来放到线程中执行)
#pragma mark - UITouch
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self test8];
}
#pragma mark - 组队列
//用来存放队列的
//作用:多个任务在不同的线程中异步执行,全部执行完毕后回到主线程
- (void)test9{
//1.创建一个队列组(存放队列的)
dispatch_group_t group = dispatch_group_create();
//2.将任务添加到队列组的队列中
//参数1:队列组
//参数2:队列
//参数3:任务
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[self downloadImage:@""];
NSLog(@"下载图片1");
});
dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
[self downloadImage:@""];
NSLog(@"下载图片2");
});
}
#pragma mark - !!!线程间通信
- (void)test8{
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"%@", [NSThread currentThread]);
UIImage * image = [self downloadImage:@""];
NSLog(@"%@", image);
//将图片传回主线程(将任务放到主队列中)
dispatch_async(dispatch_get_main_queue(), ^{
//在主队列中需要执行的任务
_imageView.image = image;
});
});
//3.队列组中的所有任务执行完毕后才回到主线程
//参数1:那个组的任务全部完成
//参数2:组的任务完成后执行那个组的队列任务
}
- (UIImage *)downloadImage:(NSString *)path{
//1.创建url
NSURL * url = [NSURL URLWithString:@"http://yuting.local/shareX/1092.jpg"];
NSData * data = [[NSData alloc] initWithContentsOfURL:url];
UIImage * image = [UIImage imageWithData:data];
//返回下载的图片
return image;
}
#pragma mark - 主队列
//主队列:主队列是系统创建好,专门用来存储在主线程中执行的任务的队列。添加到主队列中的任务,只能在主线程中执行的。使用的时候只需要直接去拿。
//注意:只能在主队列中异步执行任务
//主队列:在主线程中按顺序执行
//同步:不开新的线程
//结果:死锁
- (void)test7{
//1.拿到主队列
dispatch_queue_t queue = dispatch_get_main_queue();
NSLog(@"开始");
//2.将任务添加到主队列中,同步执行
for (int i = 0; i < 10; i++) {
dispatch_sync(queue, ^{
[self longTimeOperation:i];
});
}
NSLog(@"结束");
}
//主队列:在主线程中按顺序执行
//异步:在其他线程中执行(需要开启新的线程)
//结果:在主线程中按顺序一个一个执行
- (void)test6{
//1.拿到主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//2.将任务添加到主队列中,异步执行
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
[self longTimeOperation:i];
});
}
}
#pragma mark - 全局队列
//全局队列:系统为我们已经创建好的一个并发队列,使用的时候只需要直接去拿
- (void)test5{
//1.拿到全局队列
//参数1:队列优先级, 0
//参数2:预留参数
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//2.添加任务,异步执行
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
[self longTimeOperation:i];
});
}
}
#pragma mark - GCD的基本使用
//并发:可以多个任务同时执行
//异步:在其他线程中执行任务(可以开启新的线程)
//结果:多个任务在多个线程中同时执行(先“结束”,再执行任务)
- (void)test4{
//1.创建并发队列
dispatch_queue_t queue = dispatch_queue_create("bb", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"开始");
//2.将任务添加到队列中,异步执行
for (int i = 0; i < 10; i ++) {
dispatch_async(queue, ^{
[self longTimeOperation:i];
});
}
NSLog(@"结束");
}
//并发:多个任务同时执行
//同步:在当前线程中执行(不会开启新的线程)
//结果:所有任务在主线程中按顺序一个一个执行(先执行任务,再结束)
- (void)test3{
//1.创建并发队列
//DISPATCH_QUEUE_CONCURRENT 并发
dispatch_queue_t queue = dispatch_queue_create("aaa", DISPATCH_QUEUE_CONCURRENT);
NSLog(@"开始");
//2.将任务添加到队列中,同步执行
for (int i = 0; i < 10; i++) {
dispatch_sync(queue, ^{
[self longTimeOperation:i];
});
}
NSLog(@"结束");
}
//串行:任务一个一个按顺序执行
//异步:在其他线程中执行(开启新的线程)
//结果:在子线程中,任务按顺序一个一个执行(先“结束”,再执行任务)
- (void)test2{
//1.创建串行队列
dispatch_queue_t queue = dispatch_queue_create("aaa", NULL);
NSLog(@"开始");
//2.将任务添加到队列中,异步执行
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
[self longTimeOperation:i];
});
}
NSLog(@"结束");
}
//串行:任务一个一个按顺序执行
//同步:在当前线程中执行(不开启新的线程)
//结果:在主线程中,任务按顺序一个一个执行(先执行任务然后再“结束”)
- (void)test1{
//1.创建串行队列
//dispatch_queue_t 队列类型
//参数1:队列的标签(队列名),可以传任意的C语言字符串
//参数2:队列属性,传入并发或者串行
//DISPATCH_QUEUE_SERIAL (NULL) 串行
//DISPATCH_QUEUE_CONCURRENT 并发
dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_SERIAL);
//2.将一个任务添加到队列中(同步的)
//参数1:队列
//参数2:任务
// dispatch_sync(queue, ^{
//
// [self longTimeOperation:0];
//
// });
NSLog(@"开始");
//将多个任务添加到队列中
for (int i = 0; i < 10; i++) {
dispatch_sync(queue, ^{
[self longTimeOperation:i];
});
}
NSLog(@"结束");
}
#pragma mark - 任务
- (void)longTimeOperation:(int)i{
NSLog(@"%@:%d", [NSThread currentThread], i);
}