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

posted @ 2015-04-29 17:45  Norcy  阅读(206)  评论(0编辑  收藏  举报