关于GCD的学习笔记

GCD并发模型详解

本文不是百分百原创,是本人学习

http://www.cnblogs.com/ziyi--caolu/p/4846555.html

的过程中学习整理的学习笔记,方便后期复习,调用;

GCD有以下优点

1.GCD可以将花费时间极其长的任务放到后台线程,可以改善应用的响应性能
2.GCD 提供一个易于使用的并发模型而不仅仅只是锁和线程,以帮助我们避开并发陷阱
3.GCD 具有在常见模式(例如单例)上用更高性能的原语优化你的代码的潜在能力(后面会提供一个单例的medo)
4.等等

Tips:sync 同步  async 异步 serial 串行 concurrent 并行

GCD中常用的几种函数及其介绍

    获取相应的线程:

    dispatch_queue_t queue = dispatch_queue_create("com.dispatch.serial", DISPATCH_QUEUE_SERIAL);
    /*
     创建一个叫做queue的队列,com.dispatch.serial是队列的标示或名称,同工程中勿重复。
     DISPATCH_QUEUE_SERIAL标示该队列是串行队列,队列中的Block按照先进先出(FIFO)的顺序执行,实际上是单线程执行,
     DISPATCH_QUEUE_CONCURENT是并行队列,队列中的Block会被分发到多个线程去执行
     */
    
    dispatch_queue_t queue2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    /*
     获得程序进程缺省产生的鬓发队列。可设定优先级来选择高中低三个优先级队列。设置第一个参数即可。
     由于队列是系统默认生成的,所以无法调用dispatch_resume()和dispatch_suspend()来控制继续执行或者中断。需要注意的是,三个队列不代表三个线程,可能会有更多的线程。并发队列可能会根据实际情况自动产生合理的线程数,也可理解为dispatch队列实现了一个线程池的管理。对于程序逻辑是透明的官方文档解释说共有三个并发队列。但实际上还有一个更低优先级的队列。设置优先级为DIAPATCH_QUEUE_PRIORITY_BACKGROUND。
    */
    
    dispatch_queue_t queue3 = dispatch_get_main_queue();
    //获得主线程的Dispatch队列,实际是一个串行队列。同样无法控制主线程dispatch队列的执行继续或中断


使用dispatch_async or dispatch_sync函数来加载需要运行的block
    dispatch_async(queue, ^{
        //具体的block代码
        
    });
    //异步执行block,函数立即返回
    
    dispatch_sync(queue, ^{
        //具体的代码,同步执行
    });
    //同步执行的block,函数不返回,一直等到block执行完毕,编译器会根据情况优化代码,所以有时你会发现block其实还是在当前线程上执行的,并没有产生新的线程;
    
    //实际编程经验告诉我们,尽可能避免使用dispatch_sync,嵌套使用时容易引起程序死锁
    //如果queue是一个串行队列的话,这段代码立马产生死锁,因为代码1和代码2都是同步执行的,顺序就会冲突,产生死锁
    dispatch_sync(queue, ^{
        
        dispatch_sync(queue, ^{
            //代码1
        });
        //代码2
    });
    
    //实际运行中,一般可以用这样的disoatch,常见的网络请求数据多线程执行模型
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //子线程中开始进行网络请求数据
        
        
        //请求完成,拿到资源,更新UI
        dispatch_sync(dispatch_get_main_queue(), ^{
            //主线程中更新UI
        });
    });
    //以上就是网络请求常见的代码,程序的后台运行和UI更新代码近走,代码逻辑一目了然
    
    
    //diapatch队列是线程安全的,可以用串行队列实现锁的功能,比如多线程写统一数据库,需要保持写入顺序和每次写入的完整性,简单的利用串行队列即可实现
    dispatch_queue_t queue4 = dispatch_queue_create("com.dispatch.writeDB", DISPATCH_QUEUE_SERIAL);
    
    - (void)writeToDB{
        dispatch_async(queue4, ^{
            //write to DB
        });
    }
    //下次调用writeDB必须等到下次调用完成后才能进行,保证writeToDB方法是线程安全的
    void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));
    //demo:
    dispatch_queue_t queue5 = dispatch_get_global_queue(0, 0);
    
    dispatch_apply(1, queue4, ^(size_t i) {
        //someBlock
        NSLog(@"log i == %ld",i);
    });
    //重复执行block,需要注意的是这个方法是同步返回,也就是说等到所有的block执行完毕才返回,如需要异步返回则嵌套在dispatch_async中来使用。多个block的运行是否并发或串行执行也依赖queue的是否并发或串行
    
    void dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
    dispatch_barrier_async(queue5, ^{
        //someCode
    });
    //这个函数可以设置同步执行的block,他会等到在他加入队列之前的block执行完毕后,才开始执行。在他之后加入的block需要等到这个block执行完毕后才开始执行。
    
    void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
    dispatch_barrier_async(queue5, ^{
        //someCode
    });
    //同上。除了他是同步返回函数,会阻塞当前线程
    
    void dispatch_after(dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block);
    dispatch_after(2.0, queue5, ^{
        //someCode
    });
    //延迟执行的block
   

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        //singletonCode
    });

    //常用单例代码

    //最后再来看看dispatch队列的一个很有特色的函数:
    void dispatch_set_target_queue(dispatch_object_t object, dispatch_queue_t queue);
    dispatch_set_target_queue(queue5, queue4);
    //他会把需要执行的任务对象制定道不同的队列中去处理。这个任务对象可以使dispatch队列,也可以是dispatch源。而且这个过程是动态的,可以实现队列的动态调度管理等等。比如说有两个队列dispatchA 和 dipatchB,这时把dispatchA只拍到diaoatchB:
    dispatch_set_target_queue(dispatchA, dipatchB);
    //如此一来,dispatchA上还未运行的block会在dispatchB上运行,这时如果暂停dispatchA的运行,
    dispatch_suspend(dispatchA);
    //则之后暂停dispatchA上原来的Block的执行,disoatchB的block则不受影响。而如果暂停dispatchB的运行,则会暂停dispatchA的运行


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值