自定义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

 

posted @ 2017-01-11 17:56  小课桌  阅读(2997)  评论(0编辑  收藏  举报