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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM