美文网首页
GCD&NSOperationQueue

GCD&NSOperationQueue

作者: GTMYang | 来源:发表于2019-05-16 13:45 被阅读0次

    GCD队列规律

    • 同步派发任务只能在当前线程执行
    • 异步派发任务可以在其他线程执行
    • 串行队列任务只能在一个线程中执行
    • 并行队列任务可以在多个线程中执行

    系统中提供的队列

    • 主队列(串行) 用dispatch_get_main_queue() 获取
    • 全局并发队列 用dispatch_get_global(优先级, 0) 获取
      四种优先级:
    #define DISPATCH_QUEUE_PRIORITY_HIGH 2
    #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
    #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
    #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
    

    自己创建队列

    dispatch_queue_create(const char *_Nullable label, 
    dispatch_queue_attr_t _Nullable attr)
    

    两种类型:
    DISPATCH_QUEUE_SERIAL 串行
    DISPATCH_QUEUE_CONCURRENT 并发

    队列使用

        dispatch_queue_t queue = dispatch_queue_create("com.ly.test", 
        DISPATCH_QUEUE_CONCURRENT);
        /// 同步派发任务
        dispatch_sync(queue, ^{
            NSLog(@"同步派发任务");
        });
        /// 异步派发任务
        dispatch_async(queue, ^{
            NSLog(@"异步派发任务");
        });
        /// 延迟派发任务
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)),queue, ^{
            NSLog(@"延迟10miao派发任务");
        });
        /// 派发只执行一次的任务
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            NSLog(@"派发只执行一次的任务");
        });
        /// 快速迭代
        dispatch_apply(10, queue, ^(size_t index) {
            NSLog(@"快速迭代第%zd次", index);
        });
    

    栅栏

    派发的栅栏任务会等待前面派发的任务完成才开始,
    栅栏任务后面的任务必须等待栅栏任务完成才能开始。

    /// gcd 栅栏
        dispatch_barrier_async(queue, ^{
            NSLog(@"gcd 栅栏任务");
        });
    

    任务组

     
        dispatch_group_t group = dispatch_group_create();
        // 任务归组方式1
        dispatch_group_async(group, queue, ^{
            NSLog(@"派发任务并归组方式1");
        });
        // 任务归组方式2
        dispatch_group_enter(group);
        dispatch_async(queue, ^{
            NSLog(@"派发任务并归组方式2");
            dispatch_group_leave(group);
        });
        
        /// 阻塞等待(DISPATCH_TIME_FOREVER一直等待; DISPATCH_TIME_NOW 相当于不等待)
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
        /// 完成通知
        dispatch_group_notify(group, queue, ^{
            NSLog(@"任务组完成通知");
        });
    

    GCD信号量 dispatch_semaphore

    信号量为0时dispatch_semaphore_wait会阻塞线程,
    代码运行中如果dispatch_semaphore不能恢复到初始值,会crash。

     /// gcd 信号量
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
        /// 信号量减1
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        /// 信号量减1
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        /// 信号量减1
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        /// 信号量减1
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        /// 信号量加1
        dispatch_semaphore_signal(semaphore);
        /// 信号量加1
        dispatch_semaphore_signal(semaphore);
        /// 信号量加1
        dispatch_semaphore_signal(semaphore);
        /// 信号量加1
        dispatch_semaphore_signal(semaphore);
    

    与NSOperationQueue比较

    NSOperationQueue 是对GCD做了面向对象的封装,任务封装到NSOperation对象中,封装产生的便利性如下:

    • NSOperation可取消,有是否取消到状态变量。已开始到任务cancel无效
    • NSOperation可设置优先级
    • NSOperation之间可设置依赖关系
    • NSOperation对象属性支持KVO

    NSOperation

    @interface NSOperation : NSObject {
    @private
        id _private;
        int32_t _private1;
    #if __LP64__
        int32_t _private1b;
    #endif
    }
    
    - (void)start;
    - (void)main;
    
    /// 任务取消
    @property (readonly, getter=isCancelled) BOOL cancelled;
    - (void)cancel;
    
    @property (readonly, getter=isExecuting) BOOL executing;
    @property (readonly, getter=isFinished) BOOL finished;
    @property (readonly, getter=isConcurrent) BOOL concurrent; // To be deprecated; use and override 'asynchronous' below
    @property (readonly, getter=isAsynchronous) BOOL asynchronous API_AVAILABLE(macos(10.8), ios(7.0), watchos(2.0), tvos(9.0));
    @property (readonly, getter=isReady) BOOL ready;
    
    /// 依赖关系管理方法
    - (void)addDependency:(NSOperation *)op;
    - (void)removeDependency:(NSOperation *)op;
    
    @property (readonly, copy) NSArray<NSOperation *> *dependencies;
    
    typedef NS_ENUM(NSInteger, NSOperationQueuePriority) {
        NSOperationQueuePriorityVeryLow = -8L,
        NSOperationQueuePriorityLow = -4L,
        NSOperationQueuePriorityNormal = 0,
        NSOperationQueuePriorityHigh = 4,
        NSOperationQueuePriorityVeryHigh = 8
    };
    
    @property NSOperationQueuePriority queuePriority;
    @property (nullable, copy) void (^completionBlock)(void) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    - (void)waitUntilFinished API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    @property double threadPriority API_DEPRECATED("Not supported", macos(10.6,10.10), ios(4.0,8.0), watchos(2.0,2.0), tvos(9.0,9.0));
    @property NSQualityOfService qualityOfService API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
    @property (nullable, copy) NSString *name API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
    
    @end
    

    NSOperationQueue

    @interface NSOperationQueue : NSObject {
    @private
        id _private;
        void *_reserved;
    }
    
    - (void)addOperation:(NSOperation *)op;
    - (void)addOperations:(NSArray<NSOperation *> *)ops waitUntilFinished:(BOOL)wait API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    
    - (void)addOperationWithBlock:(void (^)(void))block API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    
    @property (readonly, copy) NSArray<__kindof NSOperation *> *operations;
    @property (readonly) NSUInteger operationCount API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    
    @property NSInteger maxConcurrentOperationCount;
    
    @property (getter=isSuspended) BOOL suspended;
    
    @property (nullable, copy) NSString *name API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    
    @property NSQualityOfService qualityOfService API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
    
    @property (nullable, assign /* actually retain */) dispatch_queue_t underlyingQueue API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
    
    - (void)cancelAllOperations;
    - (void)waitUntilAllOperationsAreFinished;
    
    @property (class, readonly, strong, nullable) NSOperationQueue *currentQueue API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    @property (class, readonly, strong) NSOperationQueue *mainQueue API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
    
    @end
    

    相关文章

      网友评论

          本文标题:GCD&NSOperationQueue

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