GCD的基本知识
1.GCD纯C语言,为多核的并行运算提出的,GCD会自动管理线程的生命周期,程序员只需要告诉GC执行什么任务,不需要编写管理线程的代码
2.GCD的核心概念:
a.定制任务
b.将任务添加到队列中:GCD会自动的将队列的任务取出,放到对应的线程中执行
任务的取出遵循队列的先进先出原则(FIFO)
GCD执行任务的两种方式:
a.同步方式执行任务,不会创建新的线程,就在当前线程中执行操作
b.异步方式执行任务,在另一个线程中执行任务
//队列类型
//1.并发队列:可以让多个任务并发执行(自动开启多个线程同时执行任务)
//并发功能只有在异步(dispatch_async)函数下才有效;
//2.串行队列:一个接着一个执行;
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
#pragma mark - UITouch触摸事件
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self test9];
}
#pragma mark - GCD的基本使用
第一种方式串行+同步
- (void) test1{
//1.创建一个串行队列
//dispatch_queue_t 队列类型
//参数1:队列标识(队列名),可以传任意的C语言的字符串
//参数2:队列的类型(并发或者串行)
//DISPATCH_QUEUE_SERIAL 串行
//DISPATCH_QUEUE_CONCURRENT 并发
dispatch_queue_t queue = dispatch_queue_create("abc,",DISPATCH_QUEUE_SERIAL);
//2.将一个任务添加到队列中
dispatch_sync(queue,^{
//这里是线程执行的操作
[self longtimeOperation:0];
});
//同步添加
//参数1:队列 参数2:任务
// dispatch_sync(queue, ^{
//
// [self longtimeOperation:0];
// });
//如果想将多个任务添加到队列中
for (int i=0; i<10;i++) {
dispatch_sync(queue, ^{
[self longtimeOperation:i];
});
}
}
//第二种方式串行异步:在其他线程中执行,开启新的线程
//在子线程中任务一个一个地执行
- (void) test2{
//1.创建队列
dispatch_queue_t queue = dispatch_queue_create("abc", NULL);
//2.添加到队列
for (int i=0; i<10; i++) {
dispatch_async(queue, ^{
[self longtimeOperation:i];
});
}
}
//第三种方式并发同步
//在当前进程中同时执行
- (void) test3{
//1.创建队列
dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_CONCURRENT);
//2.添加到队列
for (int i = 0; i<10; i++) {
dispatch_sync(queue, ^{
[self longtimeOperation:i];
});
}
}
//第四种方式并发异步
//多个任务在多个线程中同时执行
- (void)test4{
dispatch_queue_t queue = dispatch_queue_create("abc", DISPATCH_QUEUE_CONCURRENT);
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 - 主队列
//主队列:是系统创建好专门用来存储在主线程中执行任务的队列;
//添加到主队列中的任务只能在主线程中执行的,使用的时候只需要直接去拿就可以了;
//结果:死锁
//
- (void)test7{
//1.拿到主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//2.将任务添加到主队列中,异步执行
//2.添加任务,同步执行
for (int i =0;i<10; i++) {
dispatch_sync(queue, ^{
[self longtimeOperation:i];
});
}
}
//主队列:
//异步执行:在其他线程中执行.需要开启新的线程;
- (void) test6{
//1.拿到主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//2.将任务添加到主队列中,异步执行
//2.添加任务,异步执行
for (int i =0;i<10; i++) {
dispatch_async(queue, ^{
[self longtimeOperation:i];
});
}
}
#pragma mark - 线程之间的通信
- (void) test8{
//自己的子线程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSLog(@"%@",[NSThread currentThread]);
//NSURL url = []
UIImage *image = [self downLoadImagewithUrl:@""];
//将图片传回主线程
dispatch_async(dispatch_get_main_queue(), ^{
//在主队列中需要执行的任务
_imageView.image = image;
});
});
}
- (UIImage *)downLoadImagewithUrl:(NSString *)path{
//1.创建URL
// NSURL *url = [NSURL URLWithString:@"http://image.baidu.com/search/down?tn=download&ipn=dwnl&word=download&ie=utf8&fr=result&url=http%3A%2F%2Fimgsrc.baidu.com%2Fforum%2Fw%253D580%2Fsign%3Da7bfe99adbf9d72a17641015e42b282a%2F5dfed5628535e5dd5ae2287a74c6a7efcf1b6201.jpg&thumburl=http%3A%2F%2Fimg3.imgtn.bdimg.com%2Fit%2Fu%3D3096927341%2C3524930798%26fm%3D21%26gp%3D0.jpg"];
NSURL *url = [NSURL URLWithString:path];
NSData *data = [[NSData alloc]initWithContentsOfURL:url];
UIImage *image = [UIImage imageWithData:data];
return image;
}
}
#pragma mark - 组队列
//用来存放队列
//多个任务在不同的线程中需要异步执行,全部执行完毕后回到主线程
- (void)test9{
//1.创建一个队列组,用来存放队列的;
dispatch_group_t group = dispatch_group_create();
//参数1:队列组
//参数2:队列
//参数3:任务
//2.将任务添加到队列组的队列中
dispatch_group_async(group,dispatch_get_global_queue(0,0), ^{
[self downLoadImagewithUrl:@"http://image.baidu.com/search/down?tn=download&ipn=dwnl&word=download&ie=utf8&fr=result&url=http%3A%2F%2Fimgsrc.baidu.com%2Fforum%2Fw%253D580%2Fsign%3Da7bfe99adbf9d72a17641015e42b282a%2F5dfed5628535e5dd5ae2287a74c6a7efcf1b6201.jpg&thumburl=http%3A%2F%2Fimg3.imgtn.bdimg.com%2Fit%2Fu%3D3096927341%2C3524930798%26fm%3D21%26gp%3D0.jpg"];
NSLog(@"下载图片1");
});
dispatch_group_async(group,dispatch_get_global_queue(0,0), ^{
[self downLoadImagewithUrl:@"http://image.baidu.com/search/down?tn=download&ipn=dwnl&word=download&ie=utf8&fr=result&url=http%3A%2F%2Fimg5.duitang.com%2Fuploads%2Fitem%2F201407%2F09%2F20140709133734_sc8FR.jpeg&thumburl=http%3A%2F%2Fimg5.imgtn.bdimg.com%2Fit%2Fu%3D3045961850%2C3296329825%26fm%3D21%26gp%3D0.jpg"];
NSLog(@"下载图片2");
});
//3.所有任务执行完毕后回到主线程
//参数1:哪个组的任务全部完成
//参数2:组的任务完成后执行哪个队列的任务
dispatch_group_notify(group,dispatch_get_main_queue(), ^{
NSLog(@"回到了主线程");
NSLog(@"%@",[NSThread currentThread]);
});
}
#pragma mark - 任务
-(void)longtimeOperation:(int) i{
//这是一个任务,拿到当前线程并打印
NSLog(@"%@,%d",[NSThread currentThread],i);
}