您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
iOS-多线程之GCD
 
作者:Mazy_ma 来源:博客 发布于:2016-8-4
  1478  次浏览      20
 

在说GCD之前,先说几个核心的概念

任务:执行什么操作

队列:用来存放任务

1 - 并发队列(Concurrent Dispatch Queue)
可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
并发功能只有在异步(dispatch_async)函数下才有效

2 - 串行队列(Serial Dispatch Queue)
让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

同步和异步的区别

同步:只能在当前线程中执行任务,不具备开启新线程的能力

异步:可以在新的线程中执行任务,具备开启新线程的能力

GCD使用步骤

一、创建任务

二、将任务添加到队列中

GCD会自动将队列中的任务取出,放到对应的线程中执行

任务的取出遵循队列的FIFO原则:先进先出,后进后出

GCD线程队列的创建方法

1、创建一个串行队列

/**
* 创建一个串行队列
*
* @param "Mazy" 队列的标示符
* @param DISPATCH_QUEUE_SERIAL 串行队列
DISPATCH_QUEUE_CONCURRENT 并发队列
*
* @return 返回串行队列
*/
dispatch_queue_t serialQueue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_SERIAL);

2、创建一个并发队列

/**
* 创建一个并发队列
*
* @param "Mazy" 队列的标示符
* @param DISPATCH_QUEUE_CONCURRENT 并发队列
*
* @return 返回并发队列
*/
dispatch_queue_t concurrentQueue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_CONCURRENT);

3、获得全局并发队列

/**
* 获得全局并发队列
*
* @param DISPATCH_QUEUE_PRIORITY_DEFAULT 线程队列的优先级

DISPATCH_QUEUE_PRIORITY_HIGH 2 高
DISPATCH_QUEUE_PRIORITY_DEFAULT 0 一般 默认
DISPATCH_QUEUE_PRIORITY_LOW (-2) 低
DISPATCH_QUEUE_PRIORITY_BACKGROUND 很低

* @param 0 系统保留参数
*
* @return 返回全局并发队列
*/
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

3、获得主队列

/**
* 获得主队列
*
* @return 返回主线程队列
*/
dispatch_queue_t mainQueue = dispatch_get_main_queue();

同步/异步 + 串行/并发队列的组合

1、同步 + 串行队列

// 同步 + 串行队列:不会开启新的线程,在当前线程执行任务。任务是串行的,执行完一个任务,再执行下一个任务
-(void)sync_serial {
// 创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_SERIAL);
// 同步执行三个任务
dispatch_sync(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}

打印结果:

总结:没有创建新线程,主线程执行任务,任务串行执行

2、异步 + 串行队列

// 异步 + 串行队列:开启新的线程,但只开启一条
-(void)async_serial {
// 创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_SERIAL);
// 异步执行三个任务
dispatch_async(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}

打印结果:

总结:开启了一条线程,任务串行执行

3、同步 + 并发队列

// 同步 + 并发队列:不会开启新的线程
-(void)sync_concurrent {
// 创建一个全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 同步执行三个任务
dispatch_sync(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_sync(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}

打印结果:

总结:不开启新线程,主线程执行任务,任务也是顺序执行

4、异步 + 并发队列

// 异步 + 并发队列:同时开启多条线程
-(void)async_concurrent {
// 创建一个全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 异步执行三个任务
dispatch_async(queue, ^{
NSLog(@"1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"2 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"3 %@",[NSThread currentThread]);
});
}

打印结果:

总结:开启多条线程,并发执行任务

GCD线程之间的通信

从子线程回到主线程

从子线程回到主线程
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
});
});


线程之间的通信具体实现实例

// 创建 异步 全局并发队列
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 图片的网络路径
NSURL *url = [NSURL URLWithString:@"http://xxx.jpg"];

// 加载图片
NSData *data = [NSData dataWithContentsOfURL:url];

// 生成图片
UIImage *image = [UIImage imageWithData:data];

// 回到主线程设置图片
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = image;
});
});

GCD的其他使用

延迟执行

/**
* 延迟执行
*/
-(void)delay {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"---我被延迟了3秒执行---");
});
}

其他延迟执行方法

// method 1
[self performSelector:@selector(do_method) withObject:nil afterDelay:3.0];

// method 2
[NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(do_method) userInfo:nil repeats:NO];

只执行一次(用于实现单例模式)

/**
* 只执行一次
*/
-(void)onlyOnce {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"---我只会被执行一次---");
});
}

快速遍历

/**
* 快速遍历
*/
-(void)apply {
// 创建一个全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
NSInteger count = 10;
dispatch_apply(count, queue, ^(size_t index) {
NSLog(@"%zd--%@",index,[NSThread currentThread]);
});
}

打印结果:

总结:开启多条线程执行任务,速度远比(for…in…) 遍历快,对于无序的遍历,此方法比较合适

创建线程群组

例如同一个文件分段下载,待所有分段任务下载完成后,合并任务

/**
* 创建线程群组
*/
-(void)group {
// 创建一个全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// 创建一个队列组
dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, queue, ^{
NSLog(@"我是任务-1 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是任务-2 %@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"我是任务-3 %@",[NSThread currentThread]);
});

// 待群组中的每个任务执行完成后,执行此方法
dispatch_group_notify(group, queue, ^{
NSLog(@"我是终极任务,只有在group里面的任务执行完毕后才执行");
NSLog(@"%@",[NSThread currentThread]);

});
}

打印结果:

总结:开启多条线程,去执行群组中的任务,当群组内的三个任务执行完毕后,再去执行notify里面的任务

创建屏障线程队列

/**
* 创建屏障线程队列
*/
-(void)barrier {
// 创建一个并发队列
dispatch_queue_t queue = dispatch_queue_create("Mazy", DISPATCH_QUEUE_CONCURRENT);
// 创建四个异步任务
dispatch_async(queue, ^{
NSLog(@"我是任务-1 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"我是任务-2 %@",[NSThread currentThread]);
});

// 创建屏障线程队列
dispatch_barrier_async(queue, ^{
NSLog(@"----barrier-----%@", [NSThread currentThread]);
});

dispatch_async(queue, ^{
NSLog(@"我是任务-3 %@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"我是任务-4 %@",[NSThread currentThread]);
});
}

打印结果:

总结:会优先执行屏障前面的任务,当屏障前的所有任务执行完毕后,再去执行后面的任

注意:使用sync同步函数往当前串行队列中添加任务,会卡住当前的串行队列

   
1478 次浏览       20
 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
最新课程计划
信息架构建模(基于UML+EA)3-21[北京]
软件架构设计师 3-21[北京]
图数据库与知识图谱 3-25[北京]
业务架构设计 4-11[北京]
SysML和EA系统设计与建模 4-22[北京]
DoDAF规范、模型与实例 5-23[北京]

android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   

Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合

领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...