美文网首页
NSOperation

NSOperation

作者: heart_领 | 来源:发表于2018-10-31 09:56 被阅读17次

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

    生命周期与状态
    start 并发
    Main
    cancel
    executing
    finished
    concurrent
    asynchronous
    ready

    threadPriority & qualityOfService 服务质量 代表有更多几率被调度

    completionBlock 回调监听
    addExecutionBlock 添加执行代码块
    waitUntilFinished 等待完成—回不来报错

    addDependency 添加依赖(就能顺序执行,注意循环)
    removeDependency 移除依赖
    二、自定义NSOperation

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    typedef void(^KCCompleteHandle)(NSData *imageData,NSString *kc_urlString);
    
    @interface KCWebImageDownloadOperation : NSOperation
    
    @property (nonatomic, assign) NSInteger kc_maxConcurrentOperationCount;
    
    - (instancetype)initWithDownloadImageUrl:(NSString *)imageUrlString completeHandle:(KCCompleteHandle)completeHandle title:(NSString *)title;
    @end
    
    #import "KCWebImageDownloadOperation.h"
    #import "NSString+KCAdd.h"
    
    @interface KCWebImageDownloadOperation()
    @property (nonatomic, readwrite, getter=isExecuting) BOOL executing;
    @property (nonatomic, readwrite, getter=isFinished) BOOL finished;
    @property (nonatomic, readwrite, getter=isCancelled) BOOL cancelled;
    @property (nonatomic, readwrite, getter=isStarted) BOOL started;
    @property (nonatomic, strong) NSRecursiveLock *lock;
    @property (nonatomic, copy) NSString *urlString;
    @property (nonatomic, copy) KCCompleteHandle completeHandle;
    @property (nonatomic, copy) NSString *title;
    
    @end
    
    @implementation KCWebImageDownloadOperation
    // 因为父类的属性是Readonly的,重载时如果需要setter的话则需要手动合成。
    @synthesize executing = _executing;
    @synthesize finished = _finished;
    @synthesize cancelled = _cancelled;
    
    - (instancetype)initWithDownloadImageUrl:(NSString *)urlString completeHandle:(KCCompleteHandle)completeHandle title:(NSString *)title{
        if (self = [super init]) {
            _urlString = urlString;
            _executing = NO;
            _finished  = NO;
            _cancelled = NO;
            _lock      = [NSRecursiveLock new];
            _completeHandle = completeHandle;
            _title = title;
        }
        return self;
    }
    
    - (void)start{
    
        @autoreleasepool{
            [_lock lock];
            
            self.started = YES;
            [NSThread sleepForTimeInterval:1.5];
            NSLog(@"下载 %@",self.title);
            if (self.cancelled) {
                NSLog(@"取消下载 %@",self.title);
                return;
            }
            NSURL   *url   = [NSURL URLWithString:self.urlString];
            NSData  *data  = [NSData dataWithContentsOfURL:url]; // 这里不完美 等到后面写网络 直接写在task里面 网络请求的回调里面
            if (self.cancelled) {
                NSLog(@"取消下载 %@",self.title);
                return;
            }
            if (data) {
                NSLog(@"下载完成: %@",self.title);
                [data writeToFile:[self.urlString getDowloadImagePath] atomically:YES];
                [self done];
                self.completeHandle(data,self.urlString);
            }else{
                NSLog(@"下载图片失败");
            }
            [_lock unlock];
        }
    }
    
    - (void)done{
        self.finished = YES;
        self.executing = NO;
    }
    
    /**
     取消操作的方法 --- 需要进行判断
     */
    - (void)cancel{
        
        [_lock lock];
        if (![self isCancelled]) {
            [super cancel];
            self.cancelled = YES;
            if ([self isExecuting]) {
                self.executing = NO;
            }
            if (self.started) {
                self.finished = YES;
            }
        }
        [_lock unlock];
    }
    
    #pragma mark - setter -- getter
    
    - (BOOL)isExecuting {
        [_lock lock];
        BOOL executing = _executing;
        [_lock unlock];
        return executing;
    }
    
    - (void)setFinished:(BOOL)finished {
        [_lock lock];
        if (_finished != finished) {
            [self willChangeValueForKey:@"isFinished"];
            _finished = finished;
            [self didChangeValueForKey:@"isFinished"];
        }
        [_lock unlock];
    }
    
    - (BOOL)isFinished {
        [_lock lock];
        BOOL finished = _finished;
        [_lock unlock];
        return finished;
    }
    
    - (void)setCancelled:(BOOL)cancelled {
        [_lock lock];
        if (_cancelled != cancelled) {
            [self willChangeValueForKey:@"isCancelled"];
            _cancelled = cancelled;
            [self didChangeValueForKey:@"isCancelled"];
        }
        [_lock unlock];
    }
    
    - (BOOL)isCancelled {
        [_lock lock];
        BOOL cancelled = _cancelled;
        [_lock unlock];
        return cancelled;
    }
    - (BOOL)isConcurrent {
        return YES;
    }
    - (BOOL)isAsynchronous {
        return YES;
    }
    
    + (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key {
        if ([key isEqualToString:@"isExecuting"] ||
            [key isEqualToString:@"isFinished"] ||
            [key isEqualToString:@"isCancelled"]) {
            return NO;
        }
        return [super automaticallyNotifiesObserversForKey:key];
    }
    @end
    

    相关文章

      网友评论

          本文标题:NSOperation

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