美文网首页
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