GCD学习笔记
一:GCD
全称:Grand Central Dispatch(纯C语言)
优势:
1 GCD是谓多核的并行运算提出的解决方案
2 GCD会自动利用更多的CPU内核
3 GCD会自动管理线程的生命周期(创建线程,调度任务,销毁线程)
4 程序猿只需要告诉GCD想要执行的任务,不需要编写代码
二:核心概念
1 任务 :执行生命操作
2,队列:用来存放任务
三:GCD使用的两个步骤
1 定制任务:确定想做的事
2 将任务添加到队列:GCD会自动将队列里地任务取出,放到对应的线程中执行
四:执行任务
1 用同步的方式执行任务(只能在当前线程中执行任务,不具备开新线程的能力)
dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
1>两个参数
queue;队列
block:任务
2 用异步的方法执行任务(可以在新的线程中执行任务,具备开线程的能力)
dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
五:队列的类型(队列只决定你的任务如何执行)
1 并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只能在异步中有效
* GCD默认已经提供了全局的并发队列,供整个应用环境使用,不需要手动创建
//获得全局的并发队列
dispatch_queue_t *queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2 串行队列(Serial Dispatch Queue)
让任务一个接着一个的执行
*GCD中获取串行队列有两种途径
//1,dispatch_queue_create函数创建队列
dispatch_queue_t *queues = dispatch_queue_create("puguanen.ecit.queue", NULL);
//使用主队列(跟主线程相关的队列)(用在线程之间通信)
*主队列是GCD自带的一种特殊的串行队列
*放在主队列中的任务,都会放到主线程中执行(此时,将任务放到异步函数中执行时,异步失效)
六:延时执行
1,
// 3秒后自动开启新线程 执行block中的代码
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), queue, ^{
NSLog(@"------task------%@", [NSThread currentThread]);
});
2,
// 一旦定制好延迟任务后,不会卡主当前线程
[self performSelector:@selector(download:) withObject:@"http://555.jpg" afterDelay:3];
七,一次性代码
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
<#code to be executed once#>
});
代码块中的代码只执行一次
八:代码组
两个(多个)个操作执行完之后再执行下一个操作
// 1.队列组
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 2.下载图片1
__block UIImage *image1 = nil;
dispatch_group_async(group, queue, ^{
NSURL *url1 = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/f2deb48f8c5494ee460de6182ff5e0fe99257e80.jpg"];
NSData *data1 = [NSData dataWithContentsOfURL:url1];
image1 = [UIImage imageWithData:data1];
});
// 3.下载图片2
__block UIImage *image2 = nil;
dispatch_group_async(group, queue, ^{
NSURL *url2 = [NSURL URLWithString:@"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png"];
NSData *data2 = [NSData dataWithContentsOfURL:url2];
image2 = [UIImage imageWithData:data2];
});
// 4.合并图片 (保证执行完组里面的所有任务之后,再执行notify函数里面的block)
dispatch_group_notify(group, queue, ^{
// 开启一个位图上下文
UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
// 绘制第1张图片
CGFloat image1W = image1.size.width;
CGFloat image1H = image1.size.height;
[image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
// 绘制第2张图片
CGFloat image2W = image2.size.width * 0.5;
CGFloat image2H = image2.size.height * 0.5;
CGFloat image2Y = image1H - image2H;
[image2 drawInRect:CGRectMake(0, image2Y, image2W, image2H)];
// 得到上下文中的图片
UIImage *fullImage = UIGraphicsGetImageFromCurrentImageContext();
// 结束上下文
UIGraphicsEndImageContext();
// 5.回到主线程显示图片
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = fullImage;
});
});