《谈谈NSOperation和GCD》

多线程原理:

但处理器应对多线程的情况下,并发是一种模拟状态,操作系统会让这些多线程轮流执行好,每次只执行一小段时间(通常是几十到几百毫秒),这样每个线程看起来是在同事执行。这样的一个不断在处理器上切换不用的线程的行为称之为线程调度。多线程的优点是提高了资源的占用率。

GCD和NSOperation:

GCD会充分利用设备的多核,自动科学管理线程数。NSOperation是基于GCD封装的更加面向对象的线程类型,当然也具有GCD的有点。

对比1:

GCD以block的方式添加要执行的任务,更加轻量级NSOperation作为一个操作的对象给我们提供了更多的选择。

对比2:

NSOperation可以通过NSOperationQueue控制最大并发数queue.maxConcurrentOperationCount =1,而GCD则需要借助信号量来实现。以下代码是用GCD实现了一个对最大并发数为2的任务队列。

dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_block_t block2 = dispatch_block_create(1, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"任务2执行开始");
        sleep(2);
        NSLog(@"任务2执行完%@",[NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_block_t block1 = dispatch_block_create(1, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"任务1执行开始");
        sleep(2);
        NSLog(@"任务1执行完%@",[NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_block_t block3 = dispatch_block_create(1, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"任务3执行开始");
        sleep(2);
        NSLog(@"任务3执行完%@",[NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_block_t block4 = dispatch_block_create(1, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"任务4执行开始");
        sleep(2);
        NSLog(@"任务4执行完%@",[NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
    dispatch_async(dispatch_get_global_queue(0, 0), block1);
    dispatch_async(dispatch_get_global_queue(0, 0), block2);
    dispatch_async(dispatch_get_global_queue(0, 0), block3);
    dispatch_async(dispatch_get_global_queue(0, 0), block4);
对比3:

NSOperation可以设置任务的依赖,而GCD还是要借助信号量

对比4:

我们可以继承NSOperation来添加一些属性和方法,提高操作的复用性,这比GCD用简单的block插入任务队列更加自由,可以定制更多的功能。

对比5

GCD自动管理线程的生命周期,block执行完毕,线程销毁,当然可以开启线程的runloop让这个线程一直存活,GCD执行任务的生命周期很难监听。
NSOperation,可以通过KVO对象属性(excutingfinished)了解到当前任务的状态。

《谈谈NSOperation和GCD》_第1张图片
image.png

对比6:

NSOperation可以添加任务的优先级,让一些重要任务优先执行,而GCD只能按照FIFO的顺序执行。

NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"开始执行任务1");
        sleep(2);
        NSLog(@"任务1执行完毕%@",[NSThread currentThread]);
    }];
    [op1 setQueuePriority:NSOperationQueuePriorityVeryLow];
    NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"开始执行任务2");
        sleep(2);
        NSLog(@"任务2执行完毕%@",[NSThread currentThread]);
    }];
    [op2 setQueuePriority:NSOperationQueuePriorityVeryLow];
    NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"开始执行任务3");
        sleep(2);
        NSLog(@"任务3执行完毕%@",[NSThread currentThread]);
    }];
    [op3 setQueuePriority:NSOperationQueuePriorityHigh];
    NSBlockOperation * op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"开始执行任务4");
        sleep(2);
        NSLog(@"任务4执行完毕%@",[NSThread currentThread]);
    }];
    [op4 setQueuePriority:NSOperationQueuePriorityHigh];
    NSOperationQueue * queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount =1;
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue addOperation:op3];
    [queue addOperation:op4];

上述代码执行顺序是任务1->任务3->任务4->任务2

你可能感兴趣的:(《谈谈NSOperation和GCD》)