美文网首页
NSOperation

NSOperation

作者: 闲得一B | 来源:发表于2016-05-02 23:52 被阅读453次

    NSOperation的作用

    配合使用NSOperation和NSOperationQueue也能实现多线程编程
    NSOperation和NSOperationQueue实现多线程的具体步骤
    先将需要执行的操作封装到一个NSOperation对象中
    然后将NSOperation对象添加到NSOperationQueue中
    系统会自动将NSOperationQueue中的NSOperation取出来
    将取出的NSOperation封装的操作放到一条新线程中执行


    NSOperation的子类

    NSOperation是个抽象类,并不具备封装操作的能力,必须使用它的子类
    使用NSOperation子类的方式有3种
    NSInvocationOperation
    NSBlockOperation
    自定义子类继承NSOperation,实现内部相应的方法


    创建NSInvocationOperation对象

    -(id)initWithTarget:(id)targetselector:(SEL)selobject:(id)arg;
    调用start方法开始执行操作
    -(void)start;
    一旦执行操作,就会调用target的sel方法
    注意
    默认情况下,调用了start方法后并不会开一条新线程去执行操作,而是在当前线程同步执行操作
    只有将NSOperation放到一个NSOperationQueue中,才会异步执行操作


    创建NSBlockOperation对象

    +(id)blockOperationWithBlock:(void(^)(void))block;
    通过addExecutionBlock:方法添加更多的操作
    -(void)addExecutionBlock:(void(^)(void))block;
    注意:只要NSBlockOperation封装的操作数 >1,就会异步执行操作


    NSOperationQueue的作用

    NSOperation可以调用start方法来执行任务,但默认是同步执行的
    如果将NSOperation添加到NSOperationQueue(操作队列)中,系统会自动异步执行NSOperation中的操作
    添加操作到NSOperationQueue中
    -(void)addOperation:(NSOperation*)op;
    -(void)addOperationWithBlock:(void(^)(void))block;


    什么是并发数

    同时执行的任务数
    比如,同时开3个线程执行3个任务,并发数就是3
    最大并发数的相关方法
    -(NSInteger)maxConcurrentOperationCount;
    -(void)setMaxConcurrentOperationCount:(NSInteger)cat;


    取消队列的所有操作

    -(void)cancelAllOperations;
    提示:也可以调用NSOperation的-(void)cancel方法取消单个操作
    暂停和恢复队列
    -(void)setSuspended:(BOOL)b;// YES代表暂停队列,NO代表恢复队列
    -(BOOL)isSuspended;


    Operation之间可以设置依赖来保证执行顺序

    比如一定要让操作A执行完后,才能执行操作B,可以这么写
    [operationBaddDependency:operationA];// 操作B依赖于操作A
    可以在不同queue的NSOperation之间创建依赖关系


    可以监听一个操作的执行完毕

    -(void(^)(void))completionBlock;
    -(void)setCompletionBlock:(void(^)(void))block;


    自定义NSOperation的步骤很简单

    重写-(void)main方法,在里面实现想执行的任务
    重写-(void)main方法的注意点
    自己创建自动释放池(因为如果是异步操作,无法访问主线程的自动释放池)
    经常通过-(BOOL)isCancelled方法检测操作是否被取消,对取消做出响应


    一个操作需要取消时,必须等这个操作的任务执行完毕,或者在这个操作的内容不断的判断是否有取消操作。

    总结:

    回主线刷新UI

    [[NSOperationQueue mainQueue] addOprationWithBblock:^{回主线程刷新UI}];
    ------------------------------------------------------------
    操作:NSOperation、NSInvocationOperation、NSBlockOpearation。
    队列:NSOperationQueue

    当使用NSInvocationOperation时

    操作加入队列时:(注意:当前线程决定currentQueue在主队列还是在子队列)
    1、不需要调用start方法,如果调用start方法会崩溃。
    2、在主队列时(和当前线程无关)在主线程执行
    3、在自定义队列时=> [[NSOperationQueue alloc]init](和当前线程无关)在子线程中执行
    不加入队列时:
    1、需要调用start方法,在当前线程中执行(主=主,子=子)
    所以:队列决定了线程在主线程还是子线程中执行

    所在队列执行线程.png
    当是用NSBlockOperation时

    不加入队列,:需要调用start方法
    直接用NSBlockOperation封装的任务会在当前线程中执行(主=主,子=子)。
    当使用addExecutionBlock添加任务后,也就是当任务的个数大于1,那么之后的任务会在子线程中执行,NSBlockOperation封装的任务还是会在主线程中执行。
    加入队列:不需要调用start方法
    会在子线程中执行任务。
    NSINvocationOperation和NSBlockOpertaion和自定义的NSOperation都可以同时加入到同一个队列中,不需要调用start方法,并且都是在子线程中执行。
    自定义NSOPeration需要将操作封装到自定的这个对象中,通过重写mian方法来实现封装任务。

    异步串行执行任务的方式

    NSOpration实现异步串行执行的方式:
    1、设置最大并发数为1。
    2、不设置并发数时,设置任务之间的依赖。
    而GCD实现异步串行执行的方式:
    1、异步+自定义串行队列(非主队列)
    2、dispatch_barrier_async栅栏函数

    NSOperation比GCD的好处

    1、能通过KVO键值观察者来实时监控operation的状态(是否执行,是否取消),而GCD无法通过KVO来实时监控。通过completBlock来回调已经执行完毕。
    2、NSOperation能通过设置依赖,使任务之间有先后顺序。GCD可以通过栅栏函数来实现。
    3、NSOperation能设置并行队列中任务(NSOperation)的优先级(设置NSOperation在queue中的优先级,可以改变操作的执⾏优先级)(优先级的作用是让优先级高的线程需要cpu时就能够得到cpu,而不是让优先级低的线程无法运行,并且可能不止一个CPU,说明:优先级高的任务,调用的几率会更大)
    NSOperation是将任务放入队列中来执行的。
    GCD是将任务放入队列中,通过同步异步函数来执行(可以多个同步异步函数)。
    而GCD是设置不同任务队列(queue)的优先级,要实现block的优先级,需要很多代码。
    GCD更简洁

    相关文章

      网友评论

          本文标题:NSOperation

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