• GCD


    GCD的工作原理是:让任务平行排队,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。

    GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行。

    dispatch queue分为下面三种:

    Serial(串行队列):又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。

              当创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。

    Concurrent(并行队列):队列中可以并发地执行多个任务,但是执行完成的顺序是随机的。

    系统同时提供给好几个并发队列。它们叫做全局调度队列(Global Dispatch Queues) 。

    目前的四个全局队列有着不同的优先级:background、low、default 以及 high。Apple 的 API 也会使用这些队列,所以添加的任何任务都不会是这些队列中唯一的任务。

    Main dispatch queue:它是全局可用的serial queue,它是在应用程序主线程上执行任务的。

    dispatch_once_t:保证执行唯一:例如创建单例

    //静态变量,保证只有一份实例,才能确保只执行一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
       //单例代码 
    });
    dispatch_queue_create:创建队列
    //串行队列
    dispatch_queue_t queue = dispatch_queue_create("Queue", DISPATCH_QUEUE_SERIAL);
    //并行队列
    dispatch_queue_t queue = dispatch_queue_create("Queue", DISPATCH_QUEUE_CONCURRENT);
     
    dispatch_after是延迟提交,不是延迟运行
    dispatch_suspend,dispatch_resume提供了“挂起、恢复”队列的功能,简单来说,就是可以暂停、恢复队列上的任务。但是这里的“挂起”,并不能保证可以立即停止队列上正在运行的block。
    文档指出,dispatch_suspend并不会立即暂停正在运行的block,而是在当前block执行完成后,暂停后续的block执行。
     
    用 dispatch_async 处理后台任务

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 

        do .......

            dispatch_async(dispatch_get_main_queue(), ^{

                [self doSomthing];

            }); 

        });

    首先将工作从主线程移到全局线程。因为这是一个 dispatch_async() ,Block 会被异步地提交,意味着调用线程地执行将会继续。

    dispatch_async 添加一个 Block 到队列后就立即返回了。任务会在之后由 GCD 决定执行。当需要在后台执行一个基于网络或 CPU 紧张的任务时就使用 dispatch_async ,这样就不会阻塞当前线程。

     

    dispatch_sync(): 同步地提交工作并在返回前等待它完成。使用 dispatch_sync 跟踪你的调度障碍工作,或者当你需要等待操作完成后才能使用 Block 处理过的数据。

     

     

    dispatch_sync()dispatch_async() 实例分析

     

     

    dispatch_sync例

    1. - (void)viewDidLoad 
    2.   [super viewDidLoad]; 
    3.   dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    4.       NSLog(@"First Log"); 
    5.   }); 
    6.   NSLog(@"Second Log"); 
    1. 主队列一路按顺序执行任务——接着是一个实例化 UIViewController 的任务,其中包含了 viewDidLoad 。
    2. viewDidLoad 在主线程执行。
    3. 主线程目前在 viewDidLoad 内,正要到达 dispatch_sync 。
    4. dispatch_sync Block 被添加到一个全局队列中,将在稍后执行。进程将在主线程挂起直到该 Block 完成。
      同时,全局队列并发处理任务;要记得 Block 在全局队列中将按照 FIFO 顺序出列,但可以并发执行。
    5. 全局队列处理 dispatch_sync Block 加入之前已经出现在队列中的任务。
    6. 终于,轮到 dispatch_sync Block 。
    7. 这个 Block 完成,因此主线程上的任务可以恢复。
    8. viewDidLoad 方法完成,主队列继续处理其他任务。
     
    dispatch_async 例:

    - (void)viewDidLoad 

      [super viewDidLoad]; 

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 

          NSLog(@"First Log"); 

      }); 

      NSLog(@"Second Log"); 

    }

    1.主队列一路按顺序执行任务——接着是一个实例化 UIViewController 的任务,其中包含了 viewDidLoad 。
    2. viewDidLoad 在主线程执行。
    3.主线程目前在 viewDidLoad 内,正要到达 dispatch_async 。
    4.dispatch_async Block 被添加到一个全局队列中,将在稍后执行。
    5.viewDidLoad 在添加 dispatch_async 到全局队列后继续进行,主线程把注意力转向剩下的任务。
      同时,全局队列并发地处理它未完成地任务。记住 Block 在全局队列中将按照 FIFO 顺序出列,但可以并发执行。
    6.添加到 dispatch_async 的代码块开始执行。
    7.dispatch_async Block 完成,两个 NSLog 语句将它们的输出放在控制台上。
     
    两条语句的输出顺序并不总是一样的。

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     
     
     
  • 相关阅读:
    Eclipse上改动Jython代码的Comment颜色
    StaggeredGridView+universal-image-loader载入网路图片实现瀑布流
    HDU 1890 Robotic Sort
    overload和override
    FileStream大文件复制
    [Asp.Net]状态管理(Session、Application、Cache)
    c#简单自定义异常处理日志辅助类
    Socket网络编程(3)--两端通信
    [Asp.Net]状态管理(ViewState、Cookie)
    Socket网络编程(2)--服务端实现
  • 原文地址:https://www.cnblogs.com/liuziyu/p/5733662.html
Copyright © 2020-2023  润新知