美文网首页
iOS开发—GCD笔记

iOS开发—GCD笔记

作者: 葡萄糖君 | 来源:发表于2016-10-14 11:40 被阅读34次


多线程,主GCD

串行队列(Serial Dispatch Queue,等待现有处理结束)

并行队列�(Concurrent Dispatch Queue,不用等待现有处理结束)



先来看些iOS多线程的技术

pthread

纯C,需要手动创建线程、销毁线程,手动进行线程管理,代码恶心

 NSThread

Foundation框架下的OC对象,依旧需要手动管理线程。线程同步对数据的加锁会有一定的开销

GCD

纯C,不需要手动线程管理,并且会更好里利用更多的内核

NSOperationQueue

Found框架的GCD,是对GCD进行的封装



GCD的API介绍

手动创建队列

dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)

label:队列的标识符,日后可用来调试程序

attr:队列类型

DISPATCH_QUEUE_CONCURRENT : 并发队列

DISPATCH_QUEUE_SERIAL 或 NULL : 串行队列

2个常用队列

主队列

dispatch_get_main_queue();在主线程中执行的操作追加到此队列

 全局并发队列

dispatch_get_global_queue(long identifier, unsigned long flags);

该方法返回的是全局并发队列

identifier : 优先级

DISPATCH_QUEUE_PRIORITY_HIGH : 高优先级

DISPATCH_QUEUE_PRIORITY_DEFAULT : 默认优先级

DISPATCH_QUEUE_PRIORITY_LOW : 低优先级

DISPATCH_QUEUE_PRIORITY_BACKGROUND : 后台优先级

flags : 暂时用不上, 传 0 即可

同步函数

dispatch_sync(dispatch_queue_t queue, ^(void)block);

在参数queue队列下同步执行block

异步函数

dispatch_async(dispatch_queue_t queue, ^(void)block);

在参数queue队列下异步执行block(开启新线程)

时间

dispatch_time(dispatch_time_t when, int64_t delta);

根据传入的时间(when)和延迟(delta)计算出一个未来的时间

延迟执行

dispatch_after(dispatch_time_t when, dispatch_queue_t queue, ^(void)block);

有了上述获取时间的函数, 则可以直接把时间传入, 然后定义该延迟执行的block在哪一个queue队列中执行.

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            //  code to be executed after a specified delay

});

注意 : 延迟执行不是在指定时间后执行任务处理, 而是在指定时间后将处理追加到队列中, 这个是要分清楚的

队列组

dispatch_group_create();

有时候我们想要在队列中的多个任务都处理完毕之后做一些事情, 就能用到这个Group. 同队列一样, Group在使用完毕也是需要dispatch_release掉的(MRC). 上代码

组异步函数

dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, ^(void)block);

分发Group内的并发异步函数

组通知

dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, ^(void)block)

监听group的任务进度, 当group内的任务全部完成, 则在queue队列中执行block.

栅栏

dispatch_barrier_async(dispatch_queue_t queue, ^(void)block)

在访问数据库或文件时, 为了提高效率, 读取操作放在并行队列中执行. 但是写入操作必须在串行队列中执行(避免资源抢夺问题). 为了避免麻烦, 此时dispatch_barrier_async函数作用就出来了, 在这函数里进行写入操作, 写入操作会等到所有读取操作完毕后, 形成一道栅栏, 然后进行写入操作, 写入完毕后再把栅栏移除, 同时开放读取操作. 如图

快速迭代

dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){

// code here

});

执行10次代码, index顺序不确定. dispatch_apply会等待全部处理执行结束才会返回. 意味着dispatch_apply会阻塞当前线程. 所以dispatch_apply一般用于异步函数的block中

一次性代码

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

           // 只执行1次的代码(这里面默认是线程安全的)

});

挂起和恢复

dispatch_suspend(queue)

挂起指定的queue队列, 对已经执行的没有影响, 追加到队列中尚未执行的停止执行.

dispatch_resume(queue)

恢复指定的queue队列, 使尚未执行的处理继续执行.

GCD的注意点

因为在ARC下, 不需要我们释放自己创建的队列, 所以GCD的注意点就剩下死锁+

死锁

NSLog(@"111");

dispatch_sync(dispatch_get_main_queue(), ^{

            NSLog(@"222");

});

NSLog(@"333");

输出结果是

111

为什么? 看下图

毫无疑问会先输出111, 然后在当前队列下调用dispatch_sync函数, dispatch_sync函数会把block追加到当前队列上, 然后等待block调用完毕该函数才会返回, 不巧的是, block在队列的尾端, 而队列正在执行的是dispatch_sync函数. 现在的情况是, block不执行完毕, dispatch_sync函数就不能返回, dispatch_sync不返回, 就没机会执行block函数. 这种你等我, 我也等你的情况就是死锁, 后果就是大家都执行不了, 当前线程卡死在这里.

GCD的使用场景

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

             // 执行耗时操作

dispatch_async(dispatch_get_main_queue(), ^{

            // 回到主线程作刷新UI等操作

     });

});

单例

单例也就是在程序的整个生命周期中, 该类有且仅有一个实例对象, 此时为了保证只有一个实例对象, 我们这里用到了dispatch_once函数

static XXTool _instance;

+ (instancetype)allocWithZone:(struct _NSZone )zone {

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

                    _instance = [self allocWithZone:zone];

       });

       return _instance;

}

+ (instancetype)sharedInstance {

          static dispatch_once_t onceToken;

         dispatch_once(&onceToken, ^{

                  _instance = [[self alloc] init];

         });

         return _instance;

}

- (id)copy {

            return _instance;

}

- (id)mutableCopy {

          return _instance;

}

相关文章

  • iOS开发多线程之GCD

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 GCD...

  • iOS开发之GCD并发队列

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 03 ...

  • iOS开发之GCD同步任务加强

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 004...

  • iOS开发之GCD串行队列

    iOS开发多线程之GCDiOS开发之GCD同步任务加强iOS开发之GCD串行队列iOS开发之GCD并发队列 实例d...

  • iOS 开发之 GCD 不同场景使用

    iOS 开发之 GCD 不同场景使用 本文在iOS 开发值 GCD 基础 的基础上,继续总结了 GCD 的一些AP...

  • iOS开发—GCD笔记

    多线程,主GCD 串行队列(Serial Dispatch Queue,等待现有处理结束) 并行队列�(Concu...

  • IOS GCD

    转载: IOS GCD GCD 是在iOS开发多线程技术里面,使用最简单,执行效率最高的,是相对底层的API,都是...

  • iOS 开发之 GCD 基础

    iOS 开发之 GCD 基础 本文主要为 GCD 的 队列和执行方法等基础总结,目录如下: [TOC] GCD是什...

  • iOS开发笔记-GCD

    前言 很多人在同步、异步、串行、并行和死锁这几个名词的漩涡中渐渐放弃治疗。本文将使用图文表并茂的方式给大家形象地解...

  • 【Objective-c】_蓝牙开发

    ios蓝牙开发学习笔记(一)蓝牙概述 ios蓝牙开发学习笔记(二)central角色的实现 ios蓝牙开发学习笔记...

网友评论

      本文标题:iOS开发—GCD笔记

      本文链接:https://www.haomeiwen.com/subject/bywakttx.html