美文网首页iOS Developer程序员
NSOperationQueue、NSOperation及其子类

NSOperationQueue、NSOperation及其子类

作者: iOS_aFei | 来源:发表于2017-02-26 19:17 被阅读0次

    上篇文章写到GCD,GCD的优点是我们只需要定义想要执行的任务并追加到适当的Dispatch Queue中,GCD负责生成线程、计划执行任务并管理线程的生命周期,其线程管理是作为系统的一部分来实现的,因此可统一管理,所以效率很高,而且形式上十分简洁。

    GCD看似很完美了,但是GCD是基于C语言开发的,而NSOperation是基于GCD且面向对象的技术,比GCD多了一些简单实用的功能。虽然NSOperation会增加额外的开销,但是更加灵活。NSOperation对应GCD的任务,NSOperationQueue对应GCD的队列。

    NSOperation

    NSOperation是一个抽象类,我们创建需要执行的任务时,需要使用其子类。Apple为我们定义了两个NSOperation的子类:NSInvocationOperation和NSBlockOperation,另外我们可以自定义NSOperation的子类。

    NSOperationQueue

    有两种NSOperationQueue:

    主队列:通过下面方法获取,放到主队列的任务在主线程执行

    NSOperationQueue*queue = [NSOperationQueuemainQueue];

    非主队列

    NSOperationQueue*queue = [[NSOperationQueuealloc]init];

    非主队列既可以并发执行任务也可以串行执行任务,通过设置最大并发数来控制。最大并发数默认为-1,表示不受限制,如果最大并发数为1则是串行队列。非主队列无论是并发队列还是串行队列都不在主线程中执行。

    NSOperation可以调用start方法来执行任务,而不用加入到NSOperationQueue中,但是该任务将会在当前线程同步执行。

    NSInvocationOperation

    NSInvocationOperation *io = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest) object:nil];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    [queue addOperation:io];

    - (void)invocationTest {

    for(int i =0; i <100; i++) {

    NSLog(@"mainThread: %@, currentThread: %@", [NSThreadmainThread], [NSThreadcurrentThread]);

    }

    }

    NSBlockOperation

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^ {

    for(int i =0; i <100; i++) {

    NSLog(@"%@",[NSThread currentThread]);

    }

    }];

    [queue addOperation:bo];

    自定义非并发的NSOperation子类:

    我们要自定义初始化方法,并重写- (void)main {};方法,在此方法中需要能相应取消时间。

    其余方法:

    NSBlockOperation的addExecutionBlock方法:

    NSBlockOperation *blockOperation = [NSBlockOperationblock OperationWithBlock:^{

    NSLog(@"block1 : currentThread: %@", [NSThread currentThread]);

    sleep(3);

    }];

    [blockOperation addExecutionBlock:^{

    NSLog(@"block2 : currentThread: %@", [NSThread currentThread]);

    sleep(3);

    }];

    [blockOperation addExecutionBlock:^{

    NSLog(@"block3 : currentThread: %@", [NSThread currentThread]);

    sleep(3);

    }];

    [blockOperation start];

    结果:Block1是在主线程中执行的,block2和block3不是。

    添加依赖:

    [io addDependency:bo];

    io会在bo执行完后执行,不同队列的operation之间可以添加依赖。

    可通过下面方法执行operation完毕后的操作。

    io.completionBlock= ^{

    NSLog(@"finish");

    };

    我们经常需要在非主线程完成后回到主线程刷新UI:

    NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^ {

    for(inti =0; i <100; i++) {

    NSLog(@"%@",[NSThread currentThread]);

    }

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{

    NSLog(@"=====%@",[NSThreadcurrentThread]);

    }];;

    }];

    暂停任务:

    queue.suspended = YES;

    恢复任务:

    queue.suspended=NO;

    取消所有任务,一旦取消不可逆

    [queue cancelAllOperations];

    暂停和取消只能暂停或取消处于等待状态的任务,不能暂停或取消正在执行中的任务


    相关文章

      网友评论

        本文标题:NSOperationQueue、NSOperation及其子类

        本文链接:https://www.haomeiwen.com/subject/uffawttx.html