NSOperation,NSOperationQueue

2019-11-22  本文已影响0人  廖小凡

一.NSOperation

NSOperation是苹果提供的对于多线程的一套解决方案,基于GCD的封装,比GCD简单实用,代码可读性高,完全面向对象,需要用到子类NSInvocationOperation,NSBlockOperation来封装任务

1.NSInvocationOperation
    NSInvocationOperation * op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(opAction:) object:nil];
    [op start];
2.NSBlockOperation
    NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{
       
        NSLog(@"%@",[NSThread currentThread]);
    }];
    [blockOp1 start];

NSOperation单独使用时不会创建新的线程执行任务的,都是在当前线程执行的,前面两段打印都是在主线程

3. addExecutionBlock
    NSBlockOperation *blockOp2 = [[NSBlockOperation alloc]init];
    [blockOp2 addExecutionBlock:^{
       
        NSLog(@"%@",[NSThread currentThread]);
    }];

NSBlockOperation的addExecutionBlock可以新开线程去执行任务,是在子线程执行的

二.NSOperationQueue

1.队列
    NSOperationQueue *mainQpepe = [NSOperationQueue mainQueue];
    
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];

NSOperationQueue有两种队列,主队列跟其他队列

2.操作
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    NSInvocationOperation * op = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(opAction:) object:nil];
    NSBlockOperation *block = [NSBlockOperation blockOperationWithBlock:^{
       
        NSLog(@"%@",[NSThread currentThread]);
    }];
    [queue addOperation:op];
    [queue addOperation:block];

NSOperation需要添加到NSOperationQueue里面执行,才能实现多线程

3.串行,并行

主队列都是串行的,自定义队列才有串行跟并行,通过设置maxConcurrentOperationCount这个属性,设置最大并发数。
默认情况下为-1,表示不进行限制,可进行并发执行。
为1的时候,串行队列,大于1为并发队列

    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    queue.maxConcurrentOperationCount = 2;
4.操作依赖跟优先级

操作之间还能添加依赖,addDependency,比如操作b需要在操作a执行后再执行,队列又是并发队列

    NSInvocationOperation * a = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(opAction:) object:nil];
    NSBlockOperation *b = [NSBlockOperation blockOperationWithBlock:^{
       
        NSLog(@"%@",[NSThread currentThread]);
    }];
    
    [b addDependency:a];
    [queue addOperation:a];
    [queue addOperation:b];

NSOperation 提供了queuePriority(优先级)属性,queuePriority属性适用于同一操作队列中的操作,不适用于不同操作队列中的操作。
添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后进入就绪状态的操作的开始执行顺序(非结束执行顺序)由操作之间相对的优先级决定(优先级是操作对象自身的属性)。
举个例子,现在有4个优先级都是 NSOperationQueuePriorityNormal(默认级别)的操作:op1,op2,op3,op4。其中 op3 依赖于 op2,op2 依赖于 op1,即 op3 -> op2 -> op1。现在将这4个操作添加到队列中并发执行。
因为 op1 和 op4 都没有需要依赖的操作,所以在 op1,op4 执行之前,就是处于准备就绪状态的操作。
而 op3 和 op2 都有依赖的操作(op3 依赖于 op2,op2 依赖于 op1),所以 op3 和 op2 都不是准备就绪状态下的操作。

5.常用属性方法
//NSOperation
//取消操作方法,可取消操作,实质是标记 isCancelled 状态。
- (void)cancel;
//判断操作状态方法,判断操作是否已经结束。
- (BOOL)isFinished;
//判断操作是否已经标记为取消。
- (BOOL)isCancelled;
//判断操作是否正在在运行。
- (BOOL)isExecuting;
//判断操作是否处于准备就绪状态,这个值和操作的依赖关系相关。
- (BOOL)isReady;
//操作同步,阻塞当前线程,直到该操作结束。可用于线程执行顺序的同步。
- (void)waitUntilFinished;
//completionBlock 会在当前操作执行完毕时执行 completionBlock。
- (void)setCompletionBlock:(void (^)(void))block;
//添加依赖,使当前操作依赖于操作 op 的完成。
- (void)addDependency:(NSOperation *)op;
//移除依赖,取消当前操作对操作 op 的依赖。
- (void)removeDependency:(NSOperation *)op;
// 在当前操作开始执行之前完成执行的所有操作对象数组。
@property (readonly, copy) NSArray<NSOperation *> *dependencies;

//NSOperationQueue
//可以取消队列的所有操作。
- (void)cancelAllOperations;
//判断队列是否处于暂停状态。 YES 为暂停状态,NO 为恢复状态。
- (BOOL)isSuspended;
//可设置操作的暂停和恢复,YES 代表暂停队列,NO 代表恢复队列。
- (void)setSuspended:(BOOL)b;
//阻塞当前线程,直到队列中的操作全部执行完毕。
- (void)waitUntilAllOperationsAreFinished;
//向队列中添加一个 NSBlockOperation 类型操作对象。
- (void)addOperationWithBlock:(void (^)(void))block;
//向队列中添加操作数组,wait 标志是否阻塞当前线程直到所有操作结束
- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;
//当前在队列中的操作数组(某个操作执行结束后会自动从这个数组清除)。
- (NSArray *)operations;
//当前队列中的操作数。
- (NSUInteger)operationCount;
//获取当前队列,如果当前线程不是在 NSOperationQueue 上运行则返回 nil。
+ (id)currentQueue;
//获取主队列。
+ (id)mainQueue;
上一篇 下一篇

猜你喜欢

热点阅读