step 4 GCD 队列演练
串行队列
特点
- 以先进先出的方式,顺序调度队列中的任务执行
- 无论队列中所指定的执行任务函数是同步还是异步,都会等待前一个任务执行完成后,再调度后面的任务
队列创建
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL);
dispatch_queue_t queue = dispatch_queue_create("queueName", NULL);
串行队列演练
1 串行队列 同步执行
/**
提问:是否开线程?是否顺序执行?come here 的位置?
*/
- (void)gcdDemo1 {
// 1. 队列
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_SERIAL);
// 2. 执行任务
for (int i = 0; i < 10; ++i) {
NSLog(@"--- %d", i);
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
NSLog(@"come here");
}
- 串行队列 异步执行
/**
提问:是否开线程?是否顺序执行?come here 的位置?
*/
- (void)gcdDemo2 {
// 1. 队列
dispatch_queue_t q = dispatch_queue_create("foo", NULL);
// 2. 执行任务
for (int i = 0; i < 10; ++i) {
NSLog(@"--- %@ %d", [NSThread currentThread], i);
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
NSLog(@"come here");
}
并发队列
特点
- 以先进先出的方式,并发调度队列中的任务执行
- 如果当前调度的任务是同步执行的,会等待任务执行完成后,再调度后续的任务
- 如果当前调度的任务是异步执行的,同时底层线程池有可用的线程资源,会再新的线程调度后续任务的执行
队列创建
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);
并发队列演练
- 并发队列 异步执行
/**
提问:是否开线程?是否顺序执行?come here 的位置?
*/
- (void)gcdDemo3 {
// 1. 队列
dispatch_queue_t q = dispatch_queue_create("foo", DISPATCH_QUEUE_CONCURRENT);
// 2. 执行任务
for (int i = 0; i < 10; ++i) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
NSLog(@"come here");
}
- 并发队列 同步执行
/**
提问:是否开线程?是否顺序执行?come here 的位置?
*/
- (void)gcdDemo4 {
// 1. 队列
dispatch_queue_t q = dispatch_queue_create("foo", DISPATCH_QUEUE_CONCURRENT);
// 2. 执行任务
for (int i = 0; i < 10; ++i) {
dispatch_sync(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
NSLog(@"---> %i", i);
}
NSLog(@"come here");
}
主队列
特点
- 专门用来在主线程上调度任务的队列
- 不会开启线程
- 以先进先出的方式,在主线程空闲时才会调度队列中的任务在主线程执行
- 如果当前主线程正在有任务执行,那么无论主队列中当前被添加了什么任务,都不会被调度
队列获取
- 主队列是负责在主线程调度任务的
- 会随着程序启动一起创建
- 主队列只需要获取不用创建
dispatch_queue_t queue = dispatch_get_main_queue();
主队列演练
- 主队列,异步执行
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self gcdDemo1];
[NSThread sleepForTimeInterval:1];
NSLog(@"over");
}
- (void)gcdDemo1 {
dispatch_queue_t queue = dispatch_get_main_queue();
for (int i = 0; i < 10; ++i) {
dispatch_async(queue, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
NSLog(@"---> %d", i);
}
NSLog(@"come here");
}
在主线程空闲时才会调度队列中的任务在主线程执行
- 主队列,同步执行
// MARK: 主队列,同步任务
- (void)gcdDemo6 {
// 1. 队列
dispatch_queue_t q = dispatch_get_main_queue();
NSLog(@"!!!");
// 2. 同步
dispatch_sync(q, ^{
NSLog(@"%@", [NSThread currentThread]);
});
NSLog(@"come here");
}
主队列和主线程相互等待会造成死锁
同步任务的作用
同步任务,可以让其他异步执行的任务,依赖某一个同步任务
例如:在用户登录之后,再异步下载文件!
- (void)gcdDemo1 {
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
NSLog(@"登录 %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"下载 A %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"下载 B %@", [NSThread currentThread]);
});
}
- 代码改造,让登录也在异步执行
- (void)gcdDemo2 {
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);
void (^task)() = ^{
dispatch_sync(queue, ^{
NSLog(@"登录 %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"下载 A %@", [NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"下载 B %@", [NSThread currentThread]);
});
};
dispatch_async(queue, task);
}
1 主队列调度同步队列不死锁
- (void)gcdDemo3 {
dispatch_queue_t queue = dispatch_queue_create("queueName", DISPATCH_QUEUE_CONCURRENT);
void (^task)() = ^ {
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"死?");
});
};
dispatch_async(queue, task);
}
主队列在主线程空闲时才会调度队列中的任务在主线程执行
全局队列
- 是系统为了方便程序员开发提供的,其工作表现与并发队列一致
全局队列 & 并发队列的区别
1 全局队列
◦ 没有名称
◦ 无论 MRC & ARC 都不需要考虑释放
◦ 日常开发中,建议使用"全局队列"
2 并发队列
◦ 有名字,和 NSThread 的 name 属性作用类似
◦ 如果在 MRC 开发时,需要使用 dispatch_release(q); 释放相应的对象
◦ dispatch_barrier 必须使用自定义的并发队列
◦ 开发第三方框架时,建议使用并发队列
全局队列异步任务
/**
提问:是否开线程?是否顺序执行?come here 的位置?
*/
- (void)gcdDemo8 {
// 1. 队列
dispatch_queue_t q = dispatch_get_global_queue(0, 0);
// 2. 执行任务
for (int i = 0; i < 10; ++i) {
dispatch_async(q, ^{
NSLog(@"%@ - %d", [NSThread currentThread], i);
});
}
NSLog(@"come here");
}
运行效果与并发队列相同
参数
- 服务质量(队列对任务调度的优先级)/iOS 7.0 之前,是优先级
iOS 8.0(新增,暂时不能用,今年年底)
QOS_CLASS_USER_INTERACTIVE 0x21, 用户交互(希望最快完成-不能用太耗时的操作)
QOS_CLASS_USER_INITIATED 0x19, 用户期望(希望快,也不能太耗时)
QOS_CLASS_DEFAULT 0x15, 默认(用来底层重置队列使用的,不是给程序员用的)
QOS_CLASS_UTILITY 0x11, 实用工具(专门用来处理耗时操作!)
QOS_CLASS_BACKGROUND 0x09, 后台
QOS_CLASS_UNSPECIFIED 0x00, 未指定,可以和iOS 7.0 适配
iOS 7.0
DISPATCH_QUEUE_PRIORITY_HIGH 2 高优先级
DISPATCH_QUEUE_PRIORITY_DEFAULT 0 默认优先级
DISPATCH_QUEUE_PRIORITY_LOW (-2) 低优先级
DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台优先级
- 为未来保留使用的,应该永远传入0
结论:如果要适配 iOS 7.0 & 8.0,使用以下代码: dispatch_get_global_queue(0, 0);
step 4 GCD 队列演练的更多相关文章
- iOS边练边学--GCD的基本使用、GCD各种队列、GCD线程间通信、GCD常用函数、GCD迭代以及GCD队列组
一.GCD的基本使用 <1>GCD简介 什么是GCD 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 GCD的优势 G ...
- 为GCD队列绑定NSObject类型上下文数据-利用__bridge_retained(transfer)转移内存管理权-备
下面评论的好友“@Jim”给了种新的思路,就是在清除context的函数里面,用“_bridge_transfer”转换context,把context的内存管理权限重新交给ARC,这样,就不用显式调 ...
- enode框架step by step之消息队列的设计思路
enode框架step by step之消息队列的设计思路 enode框架系列step by step文章系列索引: enode框架step by step之开篇 enode框架step by ste ...
- Swift3 GCD队列优先级说明
从ios8开始,苹果引入了一个新的概念 QoS(quality of service),用于指定GCD队列的优先级. swift3之前:只有4个优先级 high > default > l ...
- OC - GCD 队列组 - 下载图片画图
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ [self downloadIma ...
- OC 线程操作 - GCD队列组
1.队列组两种使用方法2.队列组等待 wait /** 新方法 队列组一般用在在异步操作,在主线程写队列组毫无任何作用 */ - (void)GCD_Group_new_group___notify{ ...
- 多线程 GCD队列组
// DYFViewController.m // 623-08-队列组 // // Created by dyf on 14-6-23. // Copyright (c) 2014年 ___ ...
- 数据存储_FMDB数据库队列
一.代码示例 1.需要先导入FMDB框架和头文件,由于该框架依赖于libsqlite库,所以还应该导入该库. 2.代码如下: 1 // 2 // YYViewController.m 3 // 05- ...
- 4.3 多线程进阶篇<中>(GCD)
更正:队列名称的作用的图中,箭头标注的有些问题,已修正 本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” 本文源码 Demo 详见 Gith ...
随机推荐
- R语言之RCurl实现文件批量下载
前言: RCurl工具包的作者是由Duncan Temple Lang现任加州大学 U.C. Davis分校副教授.他曾致力于借助统计整合进行信息技术的探索.使用者通过RCurl可以轻易访问网页,进行 ...
- Python字符串基础一
下一篇:Python 序列通用操作介绍 写在前面 下学期开始上计算机网络的课程,现在已经在看相关书籍,希望结合python写出一个网络爬虫程序.利用学习C++后的空余时间来看看Python并在这里总结 ...
- BZOJ 4551: [Tjoi2016&Heoi2016]树
4551: [Tjoi2016&Heoi2016]树 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 748 Solved: 394[Subm ...
- ubuntu16.04安装重启后显示黑屏
环境 华硕笔记本 ubuntu16.04系统 Nvidia GTX970显卡 问题 装好ubuntu后提示重启,重启后直接黑屏 方法 开机grub界面按e键,linux打头的行,quiet后添加nom ...
- $(document).click() 在苹果手机上不能正常运行
前几天,一位同事在微信上测试一个JQuery的写的购物车功能,出现了一个很奇怪的现象,在android系统上可以正常绑定,但是在iOS上确不能用,经过排除分析,发现其使用了jquery的$(docum ...
- hdu 5017 模拟退火
题意:给出椭球面的立体解析式,要求椭球面上距离原点最近的点的距离 sol:这题要想推公式就
- Linux GDB Debugging
Catalog . GDB Introduction . GDB基本命令 1. GDB Introduction GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具,GDB主要可帮助工程师 ...
- Mysql学习笔记(四)聊聊数据库索引
小心情(可直接跳到分割线后) 今天心情好些了.一些浓的化不开的坏情绪,也渐渐的在晚上解决掉一个复杂的逻辑问题后,渐渐消散了. 今天中午去吃饭的时候,坤哥漫不经心的说:'我这么多年终于悟出了一个道理,人 ...
- 【项目】用CIFilter得到图片没办法保存到沙盒里面,显示是CGImage为空
错误代码: if (iOS9) { CGImageRef cgImage = [[CIContext new] createCGImage:outputImage fromRect:outputIma ...
- ng-controller event data
$emit只能向parent controller传递event与data $broadcast只能向child controller传递event与data $on用于接收event与data 例子 ...