• 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操作和值的复制。

  • 相关阅读:
    SVNKit学习——基于Repository的操作之print repository tree、file content、repository history(四)
    java操作svn【svnkit】实操
    python笔记38-使用zmail发各种邮件案例代码
    python笔记37-史上最好用的发邮件zmail
    python笔记3-邮件发送(smtplib)
    第9期《python3接口自动化测试》课程,6月29号开学!
    anyproxy学习4-Linux(Centos)搭建anyproxy环境
    anyproxy学习3-修改返回内容(beforeSendResponse)
    anyproxy学习2-rule模块实现接口mock功能
    anyproxy学习1-windows平台安装和抓手机app上https请求
  • 原文地址:https://www.cnblogs.com/chenyg32/p/4466257.html
Copyright © 2020-2023  润新知