GCD的使用
2016-07-25 23:06
357 查看
1.什么是GCD
GCD的全程是Crand Central Dispatch, 纯C语言的,提供了非常强大的函数API
2.GCD的核心
核心是将任务添加到队列。
任务:执行什么操作
队列:用来存放任务
任务 : 任务类型决定的是"执行"的方式
异步(dispatch_async())
特点 : 在子线程中执行,会新开线程执行
同步(dispatch_sync())
特点 : 在"当前"线程执行,不会新开线程执行,同步任务间是有序执行的
队列 : 决定了任务的"调度"的方式
串行队列
特点 : 串行队列里面的任务(无论什么任务),都是按顺序依次调度执行的,前面一个任务不"执行完",后面的任务不会被调度执行
3.GCD常用代码
延迟操作+简写
延迟操作
串行队列+同步任务
串行队列+异步任务
并行队列+同步任务
并行队列+异步任务
4.GCD主队列
主队列 : 主队列是一个"特殊"的串行队列
特点 :
主队列也是系统创建好的,只需要直接获取 get.
主队列里面的任务(无论是什么任务),"一定"是在主线程中执行的.所以用来做线程间的通信
主队列什么时候调度里面的任务执行?
***** 主队列里面的任务"只有在主线程空闲的时候,主队列才会调度里面的任务执行"
提示 : (用的挺少的)如果你创建了一个任务,这个任务不需要立即执行或者要等到主线程里面所有的操作执行完再执行,那么就可以把它添加到主队列
主队列+同步任务 == 死锁
主队列+异步任务
5.GCD全局队列
6.GCD调度组
基本使用
实现原理
GCD的全程是Crand Central Dispatch, 纯C语言的,提供了非常强大的函数API
2.GCD的核心
核心是将任务添加到队列。
任务:执行什么操作
队列:用来存放任务
任务 : 任务类型决定的是"执行"的方式
异步(dispatch_async())
特点 : 在子线程中执行,会新开线程执行
同步(dispatch_sync())
特点 : 在"当前"线程执行,不会新开线程执行,同步任务间是有序执行的
队列 : 决定了任务的"调度"的方式
串行队列
特点 : 串行队列里面的任务(无论什么任务),都是按顺序依次调度执行的,前面一个任务不"执行完",后面的任务不会被调度执行
3.GCD常用代码
延迟操作+简写
- (void)after {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"延迟操作执行");
});
}
延迟操作
- (void)afterDemo
{
NSLog(@"start");
/*
参数1 : dispatch_time_t when : 延迟多长时间,精确到纳秒
参数2 : dispatch_queue_t queue : 在哪个队列
参数3 : dispatch_block_t block : 执行哪个任务
*/
// 参数1 : dispatch_time_t when : 延迟多长时间
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
// 参数2 : dispatch_queue_t queue : 在哪个队列
// dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 参数3 : dispatch_block_t block : 执行哪个任务
dispatch_block_t block = ^{
NSLog(@"终于执行了 %@",[NSThread currentThread]);
};
// 结论 : 这个函数是个异步函数
dispatch_after(when, queue, block);
NSLog(@"mark");
}
串行队列+同步任务
dispatch_sync(dispatch_queue_create("zyn", DISPATCH_QUEUE_SERIAL), ^{
NSLog(@"串行+同步");
});
串行队列+异步任务
dispatch_async(dispatch_queue_create("zyn", DISPATCH_QUEUE_SERIAL), ^{
NSLog(@"串行队列+异步任务");
});
并行队列+同步任务
dispatch_sync(dispatch_queue_create("zyn", DISPATCH_QUEUE_CONCURRENT), ^{
NSLog(@"并发+同步队列");
});
并行队列+异步任务
dispatch_async(dispatch_queue_create("zyn", DISPATCH_QUEUE_CONCURRENT), ^{
NSLog(@"并发+异步队列");
});
4.GCD主队列
主队列 : 主队列是一个"特殊"的串行队列
特点 :
主队列也是系统创建好的,只需要直接获取 get.
主队列里面的任务(无论是什么任务),"一定"是在主线程中执行的.所以用来做线程间的通信
主队列什么时候调度里面的任务执行?
***** 主队列里面的任务"只有在主线程空闲的时候,主队列才会调度里面的任务执行"
提示 : (用的挺少的)如果你创建了一个任务,这个任务不需要立即执行或者要等到主线程里面所有的操作执行完再执行,那么就可以把它添加到主队列
主队列+同步任务 == 死锁
#pragma mark - 主队列+同步任务 == 死锁
// 一旦在主线程中把同步任务添加到主队列就造成了死锁
// 在实际的开发中需要避免 "在主线程中把同步任务添加到主队列"
- (void)GCDDemo2
{
NSLog(@"start");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 获取主队列
dispatch_queue_t main_queue = dispatch_get_main_queue();
// 同步函数/任务只在当前子线程执行
dispatch_sync(main_queue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
});
}
主队列+异步任务
#pragma mark - 主队列+异步任务
// 开不开线程?
- (void)GCDDemo1
{
// 获取主队列
dispatch_queue_t main_queue = dispatch_get_main_queue();
// 把异步任务添加到主队列
dispatch_async(main_queue, ^{
NSLog(@"%@",[NSThread currentThread]);
});
NSLog(@"mark");
}
5.GCD全局队列
// 获取全局的并发队列
/*
参数2 : 苹果不知道这个参数是干啥的,预留的,为将来的框架升级准备的
参数1 : 传入0是为了适配所有的操作系统,0标示的是默认选项
*/
dispatch_queue_t global_queue = dispatch_get_global_queue(0, 0);
6.GCD调度组
基本使用
/// 调度组的基本使用
- (void)groupDemo1
{
// 调度组
dispatch_group_t group = dispatch_group_create();
// 队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 把一个异步任务添加到调度组和队列里面
dispatch_group_async(group, queue, ^{
NSLog(@"下载图片A...%@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"下载图片B...%@",[NSThread currentThread]);
});
dispatch_group_async(group, queue, ^{
NSLog(@"下载图片C...%@",[NSThread currentThread]);
});
// 监听 group 里面的所有的异步任务是否执行完,如果执行完就自动的执行dispatch_group_notify这个函数
// 异步监听
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 写图片下载完成之后的代码
NSLog(@"刷新UI %@",[NSThread currentThread]);
});
// DISPATCH_TIME_FOREVER : 监听group里面的任务是否都执行完,直到永远(不执行完,后面的代码都不执行)
// 阻塞
// dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
NSLog(@"mark");
}
实现原理
/// 调度组实现原理
- (void)groupDemo2
{
// 调度组
dispatch_group_t group = dispatch_group_create();
// 队列
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
// 下载图片A
// 1.为图片A的下载操作,向group里面添加标记
dispatch_group_enter(group);
// 2.实现异步下载
dispatch_async(queue, ^{
NSLog(@"下载图片A...%@",[NSThread currentThread]);
// 3.这个图片下载完成,说明任务结束,那么把这个任务对应的标记从group移除
dispatch_group_leave(group);
});
// 下载图片B
// 1.为图片B的下载操作,向group里面添加标记
dispatch_group_enter(group);
// 2.实现异步下载
dispatch_async(queue, ^{
NSLog(@"下载图片B...%@",[NSThread currentThread]);
// 3.这个图片下载完成,说明任务结束,那么把这个任务对应的标记从group移除
dispatch_group_leave(group);
});
// 下载图片C
// 1.为图片C的下载操作,向group里面添加标记
dispatch_group_enter(group);
// 2.实现异步下载
dispatch_async(queue, ^{
NSLog(@"下载图片C...%@",[NSThread currentThread]);
// 3.这个图片下载完成,说明任务结束,那么把这个任务对应的标记从group移除
dispatch_group_leave(group);
});
// 异步监听 : 这个函数是在group里面的标记为空的时候,会自动调用
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 写图片下载完成之后的代码
NSLog(@"刷新UI %@",[NSThread currentThread]);
});
}
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用开发中AFNetworking库的常用HTTP操作方法小结
- iOS应用中UISearchDisplayController搜索效果的用法
- iOS App开发中的UISegmentedControl分段组件用法总结
- IOS开发环境windows化攻略
- iOS应用中UITableView左滑自定义选项及批量删除的实现
- iOS中UIAlertView警告框组件的使用教程
- 浅析iOS应用开发中线程间的通信与线程安全问题
- iOS中的UIKeyboard键盘视图使用方法小结
- 检测iOS设备是否越狱的方法
- Objective-C的内省(Introspection)用法小结