無論是掛起,還是取消全部,都無法取消正在執行的操作。
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