zoukankan      html  css  js  c++  java
  • iOS GCD

    假如有3个任务如下

    - (int)mission1
    {
        [NSThread sleepForTimeInterval:1];  //模拟耗时操作
        return 1;
    }
    
    - (int)mission2
    {
        [NSThread sleepForTimeInterval:2];  //模拟耗时操作
        return 2;
    }
    
    - (int)mission3
    {
        [NSThread sleepForTimeInterval:3];  //模拟耗时操作
        return 3;
    }

    1.普通的执行方法,消耗时间为6秒

    NSDate* startTime = [NSDate date];
    
    int ans1 = [self mission1];
    int ans2 = [self mission2];
    int ans3 = [self mission3];
    
    self.textView.text = [NSString stringWithFormat:@"%i %i %i", ans1, ans2, ans3];
    
    NSDate* endTime = [NSDate date];
    NSLog(@"%f", [endTime timeIntervalSinceDate:startTime]);
    View Code

    注意:

    由于是顺序执行,所以共消耗6秒

    2.任务完全在后台的线程中运行,消耗时间为6秒

    NSDate* startTime = [NSDate date];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        int ans1 = [self mission1];
        int ans2 = [self mission2];
        int ans3 = [self mission3];
        //必须在主线程中更新UI
        dispatch_async(dispatch_get_main_queue(), ^{
            self.textView.text = [NSString stringWithFormat:@"%i %i %i", ans1, ans2, ans3];
        });
        NSDate* endTime = [NSDate date];
        NSLog(@"%f", [endTime timeIntervalSinceDate:startTime]);
    });
    View Code

    注意:

    (1)dispatch_get_global_queue的作用是获得一个已经存在并始终可用的全局队列,第一个参数是队列优先级,第二个目前默认为0

    (2)dispatch_async的作用是队列获取程序块,并将程序块传递给一个后台线程,这里是顺序执行,所以消耗时间也是6秒

    (3)当程序块被执行完之后,整个方法可能已经退出,此时程序块外的变量startTime理应被销毁,程序块如何正确去访问startTime变量呢?其实程序块被创建的时候,会执行[startTime retain],并将返回值赋值给程序块内部的一个同名(startTime)变量

    (4)所有的UI更新都应该在主线程中完成,所以必须将self.textView.text = [NSString stringWithFormat:@"%i %i %i", ans1, ans2, ans3];扔到主线程中执行,dispatch_get_main_queue的作用是获得存在于主线程上的特殊队列

    3.任务在并发的线程中执行,消耗时间为3秒

    NSDate* startTime = [NSDate date];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        __block int ans1, ans2, ans3;
        dispatch_group_t group = dispatch_group_create();    //创建一个dispatch group
        dispatch_group_async(group, queue, ^{ans1 = [self mission1];});
        dispatch_group_async(group, queue, ^{ans2 = [self mission2];});
        dispatch_group_async(group, queue, ^{ans3 = [self mission3];});
        dispatch_group_notify(group, queue, ^{
            //必须在主线程中更新UI
            dispatch_async(dispatch_get_main_queue(), ^{
                self.textView.text = [NSString stringWithFormat:@"%i %i %i", ans1, ans2, ans3];
            });
            NSDate* endTime = [NSDate date];
            NSLog(@"%f", [endTime timeIntervalSinceDate:startTime]);
        });
    });
    View Code

    注意:

    (1)使用分配组dispatch_group将多个任务分配给多个线程来同时执行,当该组的所有线程完成的时候,会执行dispatch_group_notify中的程序块。

    (2)由于线程是并发进行所以消耗时间为3秒

    (3)ans1,ans2和ans3是在程序块中赋值,为了能够在之后使用这些变量,需要使用__block修饰。如果不用__block修饰,当ans1在程序块中被修改之后,在程序块之外ans1并不会被修改,因为程序块只是做了简单的retain操作和值的复制。

  • 相关阅读:
    文件操作
    数据补充
    小数据池
    列表
    基础知识1
    我的Python之旅开始
    正则
    模块
    迭代器与生成器
    文件操作
  • 原文地址:https://www.cnblogs.com/chenyg32/p/4466257.html
Copyright © 2011-2022 走看看