GCD多线程的使用
1.什么是GCD 全称Grand Central Dispatch,可译为“中枢调度器”,纯C语言,提供了非常多强大的函数 优点: GCD会自动管理线程的生命周期(创建线程,调度任务,销毁线程),自动利用更多的CPU内核(比如双核,四核) GCD的任务的取出遵循队列的FIFO原则:先进先出,后进后出 容易混淆的术语 1>.同步和异步主要影响:能不能开启新的线程 同步:在当前线程中执行任务,不具备开启新线程的能力 异步:在新的线程中执行任务,具备开启新线程的能力 2>.并发和串行主要影响:任务的执行方式
并发:多个任务并发(同时)执行 串行:一个任务执行完毕后,再执行下一个任务 GCD中有2个用来执行任务的函数 2.执行的任务: 1>.用同步的方式执行任务
void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
queue:队列
block:任务
2>.用异步的方式执行任务 void dispatch_async(dispatch_queue_t queue, dispatch_block_t block); 队列的类型
GCD的队列可以分为2大类型
并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务) 并发功能只有在异步(dispatch_async)函数下才有效 串行队列(Serial Dispatch Queue)
让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务) 并发队列 /**** 重要 *****/ GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建
使用
dispatch_queue_t dispatch_get_global_queue(long identifier, unsigned long flags);
返回值dispatch_queue_t 队列
参数long identifier 全局并发队列优先级 参数unsigned long flags=0 此参数暂时无用,用0即可 //全局并发队列的优先级
#define DISPATCH_QUEUE_PRIORITY_HIGH 2高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默认(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) 低 #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN后台
线程间的使用: //异步并发执行:
3. GCD 延迟执行 例如: - (void)touchesBegan:(NSSet<UITouch*> *)touches withEvent:(UIEvent*)event
{
NSLog(@"----touchesBegan");
#if 0
//错误的做法缺点:卡住当前线程
[NSThread sleepForTimeInterval:3];
NSLog(@"---下载图片");
NSLog(@"----downloadfinished");
#endif
#if0 2>1.调用NSObject的方法 //一旦定制好延迟任务后 不会卡住当前线程, 3秒后回到主线程中执行download方法不会卡住当前线程 [selfperformSelector:@selector(download) withObject:nilafterDelay:3.0f];
NSLog(@"----downloadfinished");
#endif
#if0 //3秒后回到主线程中执行block中的代码,不会造成卡顿 dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3* NSEC_PER_SEC)), queue, ^{
NSLog(@"----下载图片%@",[NSThread currentThread]);
});
NSLog(@"----downloadfinished"); #endif
//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(@"----下载图片%@",[NSThreadcurrentThread]);
});
NSLog(@"----downloadfinished"); } - (void)download
{
NSLog(@"---下载图片%@",[NSThreadcurrentThread]); }
4.一次性代码 - (void)download
{
//一次性代码使用dispatch_once_t函数能保证某段代码在程序运行过程中只被执行1次(block中的代码默认是线程安全的)
//永远只执行一次,从函数的开始到结束
staticdispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"下载图片");
});
// if (self.hasExcuted) return;
// NSLog(@"下载图片");
// self.hasExcuted = YES; }
五: GCD 队列组:
1.队列组可以解决如下需求 首先:分别异步执行2个耗时操作 其次:等2个异步操作都执行完毕后,再回到主线程执行操作 //1.队列组
dispatch_group_t group = dispatch_group_create(); dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); dispatch_group_async(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, ^{
//下载图片等操作
});
//(保证组里面所有的任务都执行完成后再执行notify函数里面的block)
dispatch_group_notify(<#dispatch_group_t group#>, <#dispatch_queue_t queue#>, ^{
//执行图片合并等操作
……..
//回到主线程显示
dispatch_async(dispatch_get_main_queue(), ^{
//显示内容等操作
});
}); 要求: //例如: //1分别下载两张图片:大图片logo
//2合并两张图片
//3显示到一个imageView上
//百度logohttp://img.baidu.com/img/baike/logo-baike.png //大图片http://img4.duitang.com/uploads/item/201208/25/20120825094010_FhGRY.thumb.700_0.jpeg
此处还可以用异步并发队列来实现此功能