无论是挂起,还是取消全部,都无法取消正在执行的操作。
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