美文网首页
NSOperation和NSOperationQueue

NSOperation和NSOperationQueue

作者: 愤怒的八哥 | 来源:发表于2019-02-12 13:34 被阅读0次

    NSOperation

    NSOperation 是个抽象类,不能用来封装操作。我们只有使用它的子类来封装操作。我们有三种方式来封装操作。
    1、使用子类 NSInvocationOperation
    2、使用子类 NSBlockOperation
    3、自定义继承自 NSOperation 的子类,通过实现内部相应的方法来封装操作。
    在不使用 NSOperationQueue,单独使用 NSOperation 的情况下系统同步执行操作,
    注意
    1、在其他线程中单独使用子类 NSInvocationOperation,操作是在当前调用的其他线程执行的,并没有开启新线程。
    2、
    NSBlockOperation 执行一个操作的情况下,操作是在当前线程执行的,并没有开启新线程。
    NSBlockOperation 还提供了一个方法 addExecutionBlock:,通过 addExecutionBlock: 就可以为 NSBlockOperation 添加额外的操作。这些操作(包括blockOperationWithBlock中的操作)可以在不同的线程中同时(并发)执行。只有当所有相关的操作已经完成执行时,才视为完成。
    如果NSBlockOperation已经执行结束或正在执行,addExecutionBlock就会崩溃
    The block should take no parameters and have no return value.
    3、自定义继承自 NSOperation 的子类

    重写main方法,main 执行完返回的时候,这个操作就结束了。如果需要复用,就要让runloop一直存活下去。
    
    类型 API 说明
    取消 - (void)cancel; 实质是标记 isCancelled 状态
    判断操作状态方法 - (BOOL)isFinished; 判断操作是否已经结束
    - (BOOL)isCancelled; 判断操作是否已经标记为取消
    - (BOOL)isExecuting; 判断操作是否正在在运行
    - (BOOL)isReady; 判断操作是否处于准备就绪状态,这个值和操作的依赖关系相关
    操作同步 - (void)waitUntilFinished; 阻塞当前线程,直到该操作结束。可用于线程执行顺序的同步
    添加操作 - (void)setCompletionBlock:(void (^)(void))block; completionBlock 会在当前操作执行完毕时执行 completionBlock

    NSOperationQueue

    类;型 API 说明
    主队列 mainQueue 凡是添加到主队列中的操作,都会放到主线程中执行(注:不包括操作使用addExecutionBlock:添加的额外操作,额外操作可能在其他线程执行)
    队列并发数控制 maxConcurrentOperationCount 控制的不是并发线程的数量,而是一个队列中同时能并发执行的最大操作数。而且一个操作也并非只能在一个线程中运行。开启线程数量是由系统决定的,不需要我们来管理
    maxConcurrentOperationCount = 1 并发数为1,串行执行
    maxConcurrentOperationCount 大于1或者为 -1 并发执行

    方法说明:

    类型 API 说明
    取消 - (void)cancelAllOperations; 可以取消队列的所有操作
    判断操作状态方法 - (BOOL)isSuspended; 判断队列是否处于暂停状态。 YES 为暂停状态,NO 为恢复状态
    - (void)setSuspended:(BOOL) 可设置操作的暂停和恢复,YES 代表暂停队列,NO 代表恢复队列
    操作同步 - (void)waitUntilAllOperationsAreFinished; 阻塞当前线程,直到队列中的操作全部执行完毕
    - (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait; 向队列中添加操作数组,wait 标志是否阻塞当前线程直到所有操作结束
    获取队列 + (id)currentQueue; 当前队列
    + (id)mainQueue; 主队列

    二者结合使用步骤

    1、创建操作:先将需要执行的操作封装到一个 NSOperation 对象中。
    2、创建队列:创建 NSOperationQueue 对象。
    3、将操作加入到队列中:将 NSOperation 对象添加到NSOperationQueue 对象中。
    之后,系统就会自动将 NSOperationQueue 中的 NSOperation 取出来,在新线程中执行操作。


    使用注意点

    操作在队列中的执行顺序

    1、操作就绪
    当一个操作的所有依赖都已经完成时,操作对象通常会进入准备就绪状态,等待执行。
    2、操作优先级(queuePriority)
    对于添加到队列中的操作,首先进入准备就绪的状态(就绪状态取决于操作之间的依赖关系),然后进入就绪状态的操作的开始执行顺序(非结束执行顺序)由操作之间相对的优先级决定(优先级是操作对象自身的属性)。

    3、操作之间的依赖关系

    - (void)addDependency:(NSOperation *)op;
    - (void)removeDependency:(NSOperation *)op;
    

    通过添加操作依赖,可以使操作顺序有序。如操作A依赖操作B,那么在队列中,永远是操作B先执行,然后才执行操作B。
    二者关系总结:
    如果一个队列中既包含高优先级操作,又包含低优先级操作,并且两个操作都已经准备就绪,那么队列先执行高优先级操作。
    如果一个队列中既包含了准备就绪状态的操作,又包含了未准备就绪的操作,未准备就绪的操作优先级比准备就绪的操作优先级高。那么,虽然准备就绪的操作优先级低,也会优先执行。优先级不能取代依赖关系。如果要控制操作间的启动顺序,则必须使用依赖关系。


    参考
    https://www.jianshu.com/p/4b1d77054b35

    相关文章

      网友评论

          本文标题:NSOperation和NSOperationQueue

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