六、线程管理————NSOperation

1、NSOperation的作用以及特点
        
        (1)是OC语言中基于GCD的面向对象的封装,NSOperation是iOS2.0推出的,iOS4之后(GCD出现)重写了NSOperation。
        
        (2)使用起来比GCD更加简单(面向对象)。同时,苹果推荐使用,使用NSOperation不用关心线程以及线程的生命周期。
        
        (3)提供了一些用GCD不好实现的功能,比如暂停,取消,最大并发数、依赖关系。当然GCD也有自己的特有,比如延迟、一次性执行、调度组。
        
        (4)NSOperation是抽象类,约束子类都具有共同的属性和方法,不能直接使用,而是使用其子类。
        
        (5)任务是并发执行的,除非遇到主队列(不是通过start命令执行任务的那种情况)。
        
        
2、NSOperationQueue 队列

(1)两种队列

    并发队列:程序员自己创建

    主队列:系统创建


(2)NSOperationQueue的作用:

    NSOperation可以调用start方法来执行任务,但默认是同步执行的。如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作。

(3)无论是使用start还是加入队列的方式来执行操作,系统都会调用NSOperation中的main方法。


(4)添加操作到队列(主队列也一样)
        
        - (void)addOperation:(NSOperation *)op;
        - (void)addOperationWithBlock:(void (^)(void))block;
        
 (5)其他一些方法和属性
        
        (BOOL)suspended  暂停
        operationCount 队列中的操作数
        maxConcurrentOperationCount 最大并发数
        +mainQueue 获得主队列
        +currentQueue 获得当前队列
        -cancelAllOperations 取消所有操作
        
        
        
        
        
3、NSOperation子类——NSInvocationOperation
        
        (1)实例
        
        //建NSInvocationOperation对象
        - (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
        //调用start方法开始执行操作,一旦执行操作,就会调用target的sel方法
        - (void)start;
    (2)注意:默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作,只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作。
        
           
        
    
4、NSOperation子类——NSBlockOperation
        
(1)实例:
        
        
        //创建NSBlockOperation对象
        + (id)blockOperationWithBlock:(void (^)(void))block;
        //通过addExecutionBlock:方法添加更多的操作
        - (void)addExecutionBlock:(void (^)(void))block;
        (2)注意:只要NSBlockOperation封装的操作数 > 1,就会异步执行操作
        
5、并发数

(1)定义:同时执行的任务数,比如,同时开3个线程执行3个任务,并发数就是3。
(2)最大并发数及相关方法:最大并发数是系统同一时间并发执行任务的最大数。系统可以开辟多个线程和队列可以拥有多个任务,但是同时执行的只能是执行设定好的最大并发数的任务,直到队列中任务执行完毕。
        - (NSInteger)maxConcurrentOperationCount;
        - (void)setMaxConcurrentOperationCount:(NSInteger)cnt;
(3)执行的过程
        a、把操作添加到队列
        b、去线程池去取空闲的线程,如果没有就创建线程
        c、把操作交给从线程池中取出的线程执行
        d、执行完成后,把线程再放回线程池中
        e、重复b,c,d直到所有的操作都执行完        


6、优先级
    
1、方法一:设置NSOperation在queue中的优先级,可以改变操作的执行优先级,注意这是NSOperation中的属性。

- (NSOperationQueuePriority)queuePriority;
- (void)setQueuePriority:(NSOperationQueuePriority)p;
2、方法二:iOS8以后推荐使用服务质量 qualityOfService属性,这是个枚举值。
3、注意:优先级只是告诉系统:在并发执行的情况下,请尽量优先调用优先级高的任务去执行,并不能绝对保证CPU全部执行优先级高的任务。
7、依赖关系

(1)定义:NSOperation之间可以设置依赖来保证执行顺序。

(2)实例

    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"op1 验证账号");
    }];
    
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"op2 扣费");
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"op3 下载应用");
    }];
    //操作依赖 不能设置相互依赖
    [op2 addDependency:op1];
    [op3 addDependency:op2];
    //把操作添加到队列中 waitUntilFinished是否等待这句代码执行完毕再来执行下面的代码
    [self.queue addOperations:@[op2,op3] waitUntilFinished:NO];
    
    //不同的队列之间也可以设置依赖关系
    [[NSOperationQueue mainQueue]addOperation:op1];


8、监听操作的完成

(1)类似于GCD的操作组,NSOperation也可以监听操作的完成,这是NSOperation种的方法:
- (void (^)(void))completionBlock;
- (void)setCompletionBlock:(void (^)(void))block;

原文地址:https://www.cnblogs.com/David-SU/p/5274388.html