• IOS 多线程03-GCD


    如果在本文之前要了解一下线程的基本知识,请访问下面的网址:http://www.cnblogs.com/alunchen/p/5337608.html

    1.简介

      GCD不仅适用于Object-C,也适用于C、C++

      GCD在C接口中添加了一些优秀的概念,比如工作单元、无痛后台处理(painless background processing)、自动线程管理,他们可在所有基于C的语言中使用。

      GCD的重要一个概念是队列,可以保证始终在主线程上执行工作的队列,非常适合非线程安全的UIKit。也可以自己创建队列。

      GCD队列遵循FIFO(先进先出)原则

    2.使用之前-block

      在使用GCD之前,一定要理解新语法block的使用,对于尽量充分利用GCD非常重要。block可替代object-c中的委托模式或C中的回调函数。这里不详细介绍block了,请参照下面文章 http://www.cnblogs.com/alunchen/p/5341057.html

    3.开启新线程与主线程

      下面我们用GCD开启一个新线程。注意的是当我们执行下面的方法,当执行完doSomething(),其实startTime已经释放了,但是注意的block一个关键点是,如果一个程序块block在执行过程中访问任何的‘外部’变量,那么该程序块block被创建时会进行一些特殊的设置工作,以允许程序块访问这些变量。所以,其实在调用dispatch_async时,startTime被retain了一次,而且程序块block内部赋给了一个内部同名startTime的新的不可变的变量。

    -(void) doSomething()  {
        NSDate *startTime = [NSDate date];
        //取得一个全局队列,优先级为DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //开启异步线程
        dispatch_async(queue, ^{ 
           //在这里做一些任何耗时的处理
            NSDate *endTime = [NSDate date];
           NSLog(@"完成时间:%f", [endTime timeIntervalSinceDate: startTime]);
        }); 
    }

      上面创建了一个异步线程,但是我们想要在异步线程中做任何更新等UI操作是不可能的,下面例子是执行完线程后,获取主线程做UI操作:

    -(void) doSomething()  {
        NSDate *startTime = [NSDate date];
        //取得一个全局队列,优先级为DISPATCH_QUEUE_PRIORITY_DEFAULT
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //开启异步线程
        dispatch_async(queue, ^{ 
           //在这里做一些任何耗时的处理
    
           //得到主线程,做UI操作
            dispatch_async(dispatch_get_main_queue(), ^{ 
                //在这里做一些更新UI等UI操作
           
           }); 
        }); 
    }

    4.并发程序块-dispatch group(提高执行速度)

       如果在新开启的异步线程A中,运行需要的时间大概需要10秒,那么我们想象一下,这个运行时间会不会太长。现在,IOS提供了一个dispatch group分派组给我们快速的执行。原理是将一个组的上下文中通过dispatch_group_async()函数异步分派的所有程序块同时运行,那就不需要10秒那么长的时间了。也可以使用dispatch_group_notify()指定一个额外的程序块,让它在组中的所有程序块运行完成时再执行。可看下面例子:

    //上面的doSomething()需要10秒,这里的少于10秒
    -(void) doSomething()  {
        NSDate *startTime = [NSDate date];
        dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        //开启异步线程
        dispatch_async(queue, ^{ 
           //在这里做一些任何耗时的处理
           doSomething2();
    
           //这里开始定义group
           dispatch_group_t group = dispatch_group_create();
           dispatch_group_async(group, queue,  ^{ 
                   //这里这一些其他的耗时处理
                   doSomething3();
           });
           
           //等待上面所有的线程运行完,这里才执行(notify的作用)
           dispatch_group_notify(group, queue, ^{
                   dispatch_async(dispatch_get_main_queue(), ^{
                           //做一些主线程更新UI的操作
                           doSomethingWithUI();
                   });
           });
    
        }); 
    }
  • 相关阅读:
    忘记 jumpserver 超级用户密码
    Linux 安装 MySQL-5.7.23
    Linux下MySQL 8.0安装配置
    H3C 端口镜像设置
    node.js+express+jade系列七:富文本编辑框的使用
    node.js+express+jade系列六:图片的上传
    node.js+express验证码的实现
    node.js定时任务:node-schedule的使用
    node.js+express+jade系列五:ajax登录
    node.js+express+jade系列四:jade嵌套的使用
  • 原文地址:https://www.cnblogs.com/alunchen/p/5338086.html
Copyright © 2020-2023  润新知