iOS基础-- GCD基础总结
2016-07-06 本文已影响1182人
云之君兮鹏
夕阳无限好,只是近黄昏!<回顾>
GCD点击大图.<思维导图供参考>
关于多线程(NSThread、NSOperation、NSOperationQueue)基础总结, 参考文章
回顾 GCD 基础只是理解:
1: 特点
1.1: 纯 C语言编写, 所以在使用的时候, 使用的是函数而不是方法.
1.2: GCD 可以充分利用多核硬件并发处理多个任务, 也就是说效率高.
1.3: GCD 使用后不用程序去管理线程的开闭, GCD 会在系统层上面动态的检测系统的状态, 开闭线程.
1.4: 管理线程的生命周期(调度任务, 销毁线程, 线程创建).
2: 核心概念:
2.1: 任务: 执行什么操作
2.2: 队列: 用来存放任务
3: 使用 GCD 两个步骤
3.1: 定制任务:确定需要做什么事情.
3.2: 将任务添加到队列当中:3.2.1: GCD 会自动将任务队列中任务取出, 放到对应的线程当中.
3.2.2: 而任务取出的时候, 遵循队列的先进先出(FIFO)原则.
4: 队列
4.1: 并发队列
4.1.1: 可以让多个任务并发 (同时) 执行 (自动开启了多个线程,同时执行任务)
4.1.2: 并发功能只能在异步函数下才会有效(否则串行执行)
4.2: 串行队列: 让任务一个接一个执行 (一个完成, 执行下一个)
4.3: 并发和串行, 决定了任务的执行方式4.3.1 并发: 多个任务 同时 执行
4.3.2 串行: 多个任务 挨个 执行
-
创建串行队列的两种方式(里面任务依次进行每个任务完全执行完成之后下个任务才会开始执行)
-
第 1 种: 系统提供的串行队列创建方式 (串行队列中比较实用的, 常用在开发中)
dispatch_queue_t queue = dispatch_get_main_queue();
-
第 2 种: 创建函数创建
参数1:系统保留字段可随意填写,为以后功能拓展留下的接口(本人理解)
参数2: 宏定义队列的类型
dispatch_queue_t queue1 = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);
-
创建并行队列两种方式(任务可以同时进行)
-
第 1 种: 系统方法创建并发并发队列(全局队列)
/*
dispatch_get_global_queue(
<#long identifier#>, 参数1: 优先级
<#unsigned long flags#>) 参数2: 系统保留关键字,暂时写0,预留接口
*/
dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);```
- 第 2 种: 函数创建
```code
dispatch_queue_t queue3 = dispatch_queue_create("queue3", DISPATCH_QUEUE_CONCURRENT);
两个执行函数(同步异步执行):
- ※ 1: 同步执行任务(sync):在一个线程中,让事情有序的执行(只能在当前的线程中执行, 不能开辟新线程)
dispatch_sync( 队列queue, ^{
NSLog(@"我是同步执行----->");
});```
- ※ 2: 异步执行任务(async): 在另一个线程中执行 (可以在新线程中开启任务, 具有开启新线程的能力)
```code
dispatch_async(队列名queue, ^{
NSLog(@"我是异步执行----->");
});```
###### 注意: 根据队列的性质可以组成不同的组合, 同步+串行 同步+并发(实际上失效) 异步+串行 异步+并发
----------------
- 创建分组(用来管理队列任务的)
```code
dispatch_group_t group = dispatch_group_create();
- 向分组中添加队列任务
dispatch_group_async(group组名, queue队列名, ^{
NSLog(@"我是第一个任务");
});
dispatch_group_async(group组名, queue队列名, ^{
NSLog(@"我是第二个任务");
});
dispatch_group_async(group组名, queue队列名, ^{
NSLog(@"我是第三个任务");
});
dispatch_group_async(group组名, queue队列名, ^{
NSLog(@"我是第四个任务");
});```
- 用来监听组内任务的任务 也就是当组里面任务都执行完了才执行的任务函数 不能第一个放到组里面 放到其他位置即可
```code
dispatch_group_notify(group组名, queue队列名, ^{
NSLog(@"我是最后任务");
});
其他几个关于队列的函数
- 任务延迟执行函数
只需要填写时间即可任务写在 block 中,
/*DISPATCH_TIME_NOW, 计算时间(从现在开始)
<#delayInSeconds#>(真正延迟时间你要写的)
NSEC_PER_SEC 程序消耗的时间从开始执行(大概是这个意思吧)
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"一日不见,十秒了%@",[NSThread currentThread]);
});
- 添加重复任务
参数1: 重复添加的次数
参数2: 添加到哪个队列
参数3 size_t : 这是标准 C语言库定义的 Unsigned int 类型
dispatch_apply(10, queue, ^(size_t index) {
NSLog(@"index---->%zu", index);
NSLog(@"addTask-->%@",[NSThread currentThread]);
});```
------------------
线程锁死
>- 原因1: dispatch_sync 在等待 任务 执行完成, 但是任务被添加到主线程里面, 在主线程里执行前面还有, 所以dispatch_sync如果在主线程中调用, 就会造成锁死.
- 原因2: dispatch_sync 是同步的, 本身就会阻塞线程, 就是主线程, 而现在又往主线程添加任务,就会造成锁死. 如下:
dispatch_sync(主线程队列, ^{
NSLog(@"同步任务永远没有机会执行 ");
--------------------------------
- #####例子1: 异步串行队列 (<small>应用的地方比较多吧,比如同时下载多个内容时候,异步可以让你去干其他事(比如听歌),串行保证你的下载是一个内容全部完成后再去完成另一个任务</small>)
```code
// 创建串行队列
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_SERIAL);
// 异步执行串行队列
dispatch_async(queue, ^{
NSLog(@"1");
NSLog(@"①");
});
dispatch_async(queue, ^{
NSLog(@"2");
NSLog(@"②");
});
dispatch_async(queue, ^{
NSLog(@"3");
NSLog(@"③");
});
dispatch_async(queue, ^{
NSLog(@"4");
NSLog(@"④");
});
有时间在写了,,,,,,