美文网首页
NSOperationQueue

NSOperationQueue

作者: 小凡凡520 | 来源:发表于2019-10-11 15:53 被阅读0次
    一、与GCD比较
    * GCD是底层的C语言构成的API,而NSOperationQueue以及相关对象是基于GCD的Objective-C对象的封装,作为一个对象,NSOperationQueue为我们提供了更多的选择
    * NSOperationQueue任务可以很方便的取消(也只能取消未执行的任务),而GCD没法停止已经加入队列的任务(其实是有的,但需要许多复杂的代码)
    * 不像GCD那样的是按FIFO顺序来执行的,NSOperation能够方便地通过依赖关系设置操作执行顺序,可以控制任务在特定的任务执行完后才执行;而GCD要实现这个功能的话,就需要通过barrier或者group来控制执行顺便,如果依赖关系复杂的话,代码逻辑就非常复杂了
    * NSOperation支持KVO(Key-Value Observing),可以方便的监听任务的状态(完成、执行中、取消等等状态)
    * NSOperation可以设置同一个队列中任务的优先级,能够使同一个并行队列中的任务区分先后地执行,而在GCD中,我们只能区分不同任务队列的优先级,如果要区分block任务的优先级,也需要大量的复杂代码
    * 还可以通过自定义NSOperation,封装任务逻辑,提高整个代码的复用度
    
    二、说明

    NSOperation相当于是NSOperationQueue中一个操作任务。NSOperation本身是一个抽象类,不能直接使用。我们可以使用系统提供的子类NSInvocationOperation(swift不支持) 和NSBlockOperation,或者自己实现NSOperation子类的方式来执行操作任务。NSOperation对象都是通过调用start方法来开始执行任务。

    三、分类
    • NSInvocationOperation
      swift 不支持
    • NSBlockOperation
    // 创建NSBlockOperation对象
    self.blockOperation = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"blockOperation1 thread:%@",[NSThread currentThread]);
    }];
    [self.blockOperation addExecutionBlock:^{
        NSLog(@"blockOperation2 thread:%@",[NSThread currentThread]);
    }];
    [self.blockOperation addExecutionBlock:^{
        NSLog(@"blockOperation3 thread:%@",[NSThread currentThread]);
    }];
    
    [self.blockOperation start];
    NSLog(@"after blockOperation");
    
    • completionBlock
    [self.invocationOperation setCompletionBlock:^{
        NSLog(@"invocationOperation completion");
    }];
    
    [self.blockOperation setCompletionBlock:^{
        NSLog(@"blockOperation completion");
    }];
    
    • NSOperationQueue
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let block = BlockOperation {
            print("1")
        }
        block.completionBlock = {
            print("end")
        }
        block.addExecutionBlock {
            print("2")
        }
        block.addExecutionBlock {
            print("3")
        }
        block.addExecutionBlock {
            print("4")
        }
        block.addExecutionBlock {
            print("5")
        }
        block.addExecutionBlock {
            print("6")
        }
        
        let queue = OperationQueue()
        queue.addOperation(block)
        
        queue .addOperation {
            print("7")
        }
    }
    
    四、添加依赖
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let block1 = BlockOperation {
            print("1")
        }
        let block2 = BlockOperation {
            print("2")
        }
        let block3 = BlockOperation {
            print("3")
        }
        let block4 = BlockOperation {
            print("4")
        }
        let block5 = BlockOperation {
            print("5")
        }
        block2.addDependency(block1)
        block3.addDependency(block2)
        block4.addDependency(block3)
        block5.addDependency(block4)
        
        block1.start()
        block2.start()
        block3.start()
        block4.start()
        block5.start()
    }
    
    五、取消操作
    [self.blockOperation cancel];
    [self.invocationOperation cancel];
    [self.queue cancelAllOperations];
    
    六、设置优先级
    [self.blockOperation setQueuePriority:NSOperationQueuePriorityHigh];
    [self.invocationOperation setQueuePriority:NSOperationQueuePriorityLow];
    
    七、暂停和继续
    [self.queue setSuspended:YES]; //暂停
    [self.queue setSuspended:NO];  //继续
    
    八、设置最大并发数

    可以通过maxConcurrentOperationCount属性设置最大并发数,该值默认为-1,由系统调度。当设置为1的时候相当于是一个同步执行的操作队列。

    九、等待 NSOperation 执行完成
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let block1 = BlockOperation {
            print("1")
        }
        
        print("start")
        
        DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + 10) {
            block1.start()
        }
        
        // 当前线程被阻塞
        block1.waitUntilFinished()
        
        print("end")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        let block1 = BlockOperation {
            print("1")
        }
        
        let queue = OperationQueue()
        queue.addOperation(block1)
        
        print("start")
        
        queue.waitUntilAllOperationsAreFinished()
        
        print("end")
    }
    
    十、监听属性
    • isExecuting 代表任务正在执行中
    • isFinished 代表任务已经执行完成,被取消也算执行完成
      注:该状态关系到依赖其的操作任务,只有在其isFinished状态为YES的时候,依赖其的操作任务才能开始执行,操作队列也是根据这个状态来决定是否将操作任务从队列中移除
    • isCancelled 代表任务已经取消执行
    • isAsynchronous 代表任务是并发还是同步执行
      注:当操作任务加入到操作队列后,会忽略该属性
    • isReady 代表任务是否已经准备执行
      注:当其依赖的操作任务都执行完时,改状态才会是YES
    十一、自定义NSOperation
    • 自定义同步NSOperation
    • 自定义并发NSOperation

    相关文章

      网友评论

          本文标题:NSOperationQueue

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