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

你可能感兴趣的:(ios)