• NSOperationQueue、NSOperation理解


    1.NSThread与NSRunLoop:
        一个单独的app应用就是一个进程,里面起码包含有一个主线程(UI线程),并可以创建多个子线程
        每个thread中默认会有一个runLoop对象,主线程的runLoop对象是运行着的,用户自己创建的子线程runLoop对象默认是没有启动的。
        如果新开的子线程只是为了完成一个耗时的任务,那么不用启动runLoop循环,如果需要子线程监控一些事情,则需开启;只有给runLoop添加了源才能保证线程一直运行存在,这些源包括timer源、输入事件等,参考:http://www.hrchen.com/2013/06/multi-threading-programming-of-ios-part-1/ 和 http://blog.sina.com.cn/s/blog_74e9d98d0101gzxq.html

    2.NSOperationQueue与NSOperation:
        一个operation就相当于一个函数块、block块、代码块,这里只是把它提高到一种任务的角度来看待,然后,任务便会有开始执行(start)、取消(cancel)、是否取消(isCancel)、是否完成(isFinishing)、暂停(pause)等状态函数,其本身是不会创建新的线程来执行它的,NSOperation本身是一个基类,不能直接使用,必须继承它。
        NSOperation中比较重要的是start和main函数,一般结合NSOperationQueue来使用,OperationQueue实质上也就是数组管理,对添加进去的operation进行管理、创建线程等;添加到queue里的operation,queue默认会调用operation的start函数来执行任务,而start函数默认又是调用main函数的。
        如果不想自定义operation,则可以简单使用系统预定义的两个operation子类:NSBlockOperation(任务块是一个block块)、NSInvocationOperation(任务块是一个函数块)
         另外,OperationQueue在使用上也有很大的缺陷,比如一旦operation添加到队列中后,就不能再对operation进行一些修改操作,否则将会出现不可预知的错误,因为operation在队列中有可能随时都会被执行;只能进行cancel或整个队列的cancelAllOperations操作,对单个operation进行cancel后,这个operation还会短暂停留在队列的operations数组里,要稍等片刻才会被移除,这样对于外界使用队列这个operation数组的情况将会出现bug,cancelAllOperations也是要等会才会全部被移除;值得一提的是,cancel和cancelAllOperations默认情况下,都不能取消已经正在执行的operation,只能取消在队列中等待的operation,如果硬要取消正在执行的,只能重写operation的main方法,并在main方法中添加对isCancel属性的监控;而且对于队列的setSuspended方法也只是暂停等待的operation,还有operation添加依赖、队列最大线程数等,功能都比较鸡肋,一切队列的方法都只能对等待的operation才能起作用。
        
        如此一来,特别对于像下载这样的,只能自定义operation对象,并重写start方法(start方法中,不一定仍然调用自身的main方法,可以自己指定执行的方法,像AFURLConnectionOperation一样)、自己创建线程;之前的operation本身是不会创建线程的,线程是在queue中创建,所以才产生并发的效果。
       
       自定义operation需要重写并注意的函数:网上说的那么多重写start main isExcuding实现KVO等  其实都是为了后面结合OperationQueue使用,如果你完全不想使用queue,则operation貌似也没有使用的必要,它本身就是一个代码块,不创建线程的,其start main函数都是为了提供给queue管理调用的,可参考AFURLConnectionOperation的实现
       NSOperation.h头文件:
    @interface NSOperation : NSObject {
    @private
        id _private;
        int32_t _private1;
    #if __LP64__
        int32_t _private1b;
    #endif
    }

    - (id)init; // designated initializer

    - (void)start; //
    - (void)main;

    - (BOOL)isCancelled;
    - (void)cancel;

    - (BOOL)isExecuting;
    - (BOOL)isFinished;

    - (BOOL)isConcurrent;

    - (BOOL)isReady;

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

    - (NSArray *)dependencies;

    typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
        NSOperationQueuePriorityVeryLow = -8L,
        NSOperationQueuePriorityLow = -4L,
        NSOperationQueuePriorityNormal = 0,
        NSOperationQueuePriorityHigh = 4,
        NSOperationQueuePriorityVeryHigh = 8
    };

    - (NSOperationQueuePriority)queuePriority;
    - (void)setQueuePriority:(NSOperationQueuePriority)p;

    #if NS_BLOCKS_AVAILABLE
    - (void (^)(void))completionBlock NS_AVAILABLE(10_6, 4_0);
    - (void)setCompletionBlock:(void (^)(void))block NS_AVAILABLE(10_6, 4_0);
    #endif

    - (void)waitUntilFinished NS_AVAILABLE(10_6, 4_0);

    - (double)threadPriority NS_AVAILABLE(10_6, 4_0);
    - (void)setThreadPriority:(double)p NS_AVAILABLE(10_6, 4_0);

    @end


  • 相关阅读:
    PP篇10 修改工单组件行
    取未清PO逻辑
    PP篇7 生产替代料齐套后处理
    PP篇9 更改计划订单
    DEBUG技巧里的问题1 双击某个变量不能显示
    HoloLens开发手记
    开始开发HoloLens应用吧 Start Developing HoloLens Apps Today
    HoloLens开发手记
    HoloLens开发手记
    HoloLens开发手记
  • 原文地址:https://www.cnblogs.com/cnsec/p/11515803.html
Copyright © 2020-2023  润新知