• 自定义NSOperation实现取消正在执行下载的操作


    无论是挂起,还是取消全部,都无法取消正在执行的操作。

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    // 移除队列里面所有的操作,但正在执行的操作无法移除
    [queue cancelAllOperations];
    
    // 挂起队列,使队列任务不再执行,但正在执行的操作无法挂起
    _queue.suspended = YES;

    我们可以自定义NSOperation,实现取消正在执行的操作。其实就是拦截main方法。

    main方法:

    1、任何操作在执行时,首先会调用start方法,start方法会更新操作的状态(过滤操作,如过滤掉处于“取消”状态的操作)。

    2、经start方法过滤后,只有正常可执行的操作,就会调用main方法。

    3、重写操作的入口方法(main),就可以在这个方法里面指定操作执行的任务。

    4、main方法默认是在子线程异步执行的

    示例代码:

    头文件

     1 #import <Foundation/Foundation.h>
     2 #import <UIKit/UIKit.h>
     3 
     4 /**
     5  自定义下载图片器:下载图片,回调给VC
     6  */
     7 @interface YSDownloadOperation : NSOperation
     8 
     9 /**
    10  类方法实例化自定义操作
    11 
    12  @param urlString 图片地址
    13  @param finishBlock 完成回调
    14  @return 自定义操作
    15  */
    16 + (instancetype)downloadImageWithURLString:(NSString *)urlString andFinishBlock:(void(^)(UIImage*))finishBlock;
    17 
    18 @end

    .m文件

     1 #import "YSDownloadOperation.h"
     2 
     3 @interface YSDownloadOperation()
     4 
     5 /**
     6  图片地址
     7  */
     8 @property(copy,nonatomic) NSString *urlString;
     9 
    10 /**
    11  回调Block,在主线程执行
    12  */
    13 @property(copy,nonatomic) void(^finishBlock)(UIImage*);
    14 
    15 @end
    16 
    17 @implementation YSDownloadOperation
    18 
    19 
    20 /**
    21  重写自定义操作的入口方法
    22  任何操作在执行时都会默认调用这个方法
    23  默认在子线程执行
    24  当队列调度操作执行时,才会进入main方法
    25  */
    26 - (void)main{
    27     // 默认在子线程执行
    28     // NSLog(@"%@",[NSThread currentThread]);
    29     
    30     NSAssert(self.urlString != nil, @"请传入图片地址");
    31     NSAssert(self.finishBlock != nil, @"请传入下载完成回调Block");
    32     
    33     // 越晚执行越好,一般写在耗时操作后面(可以每行代码后面写一句)
    34     if(self.isCancelled){
    35         return;
    36     }
    37     
    38     // 下载图片
    39     NSURL *imgURL = [NSURL URLWithString:self.urlString];
    40     NSData *imgData = [NSData dataWithContentsOfURL:imgURL];
    41     UIImage *img = [UIImage imageWithData:imgData];
    42     
    43     // 越晚执行越好,一般写在耗时操作后面(可以每行代码后面写一句)
    44     if(self.isCancelled){
    45         return;
    46     }
    47     
    48     // 传递至VC
    49     [[NSOperationQueue mainQueue] addOperationWithBlock:^{
    50         self.finishBlock(img);
    51     }];
    52 }
    53 
    54 + (instancetype)downloadImageWithURLString:(NSString *)urlString andFinishBlock:(void(^)(UIImage*))finishBlock{
    55     YSDownloadOperation *op = [[self alloc] init];
    56     
    57     op.urlString = urlString;
    58     op.finishBlock = finishBlock;
    59     
    60     return op;
    61 }
    62 
    63 @end
  • 相关阅读:
    bzoj 4883 [Lydsy1705月赛]棋盘上的守卫——并查集(思路!)
    洛谷 1979 华容道——最短路+dp
    51nod 1443 路径和树——最短路生成树
    hdu 2222 Keywords Search——AC自动机
    bzoj 2067 [Poi2004]SZN——二分+贪心
    洛谷 1084 疫情控制——二分答案+贪心(贪心思路!)
    CF 1042A Benches——二分答案(水题)
    洛谷 1314 聪明的质监员——二分答案
    洛谷P3690 LCT模板
    bzoj1875 [SDOI2009]HH去散步——矩阵快速幂
  • 原文地址:https://www.cnblogs.com/panda1024/p/6274631.html
Copyright © 2020-2023  润新知