// ImageLoadOperation.h #import <Foundation/Foundation.h> @interface ImageLoadOperation : NSOperation { NSURL *_imageURL; id _target; SEL _action; } - (id)initWithImageURL:(NSURL *)imageURL target:(id)target action:(SEL)action; @end // ImageLoadOperation.m #import "ImageLoadOperation.h" @implementation ImageLoadOperation - (id)initWithImageURL:(NSURL *)imageURL target:(id)target action:(SEL)action { if (self = [super init]) { _imageURL = [imageURL retain]; _target = target; _action = action; } return self; } - (void)main { NSData *data = [[NSData alloc] initWithContentsOfURL:_imageURL]; UIImage *image = [[UIImage alloc] initWithData:data]; [_target performSelectorOnMainThread:_action withObject:image waitUntilDone:NO]; [data release]; [image release]; } - (void)dealloc { [_imageURL release], _imageURL = nil; [super dealloc]; } @end // ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController @end // ViewController.m #import "ViewController.h" #import "ImageLoadOperation.h" @interface ViewController () { UIImageView *_imageView; NSOperationQueue *_operationQueue; } @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; UIButton *testButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [testButton setTitle:@"test button" forState:UIControlStateNormal]; [testButton setFrame:CGRectMake(20, 20, 280, 30)]; [self.view addSubview:testButton]; [testButton addTarget:self action:@selector(tesstButtonClick) forControlEvents:UIControlEventTouchUpInside]; _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20, 90, 280, 200)]; [self.view addSubview:_imageView]; _operationQueue = [[NSOperationQueue alloc] init]; } - (void)tesstButtonClick { ImageLoadOperation *operation = [[ImageLoadOperation alloc] initWithImageURL:[NSURL URLWithString:@"http://pic3.zhongsou.com/image/380ba673b49ae607633.jpg"] target:self action:@selector(didFinishLoadingImage:)]; [_operationQueue addOperation:operation]; [operation release]; } - (void)didFinishLoadingImage:(UIImage *)image { [_imageView setImage:image]; } - (void)dealloc { [_imageView release], _imageView = nil; [_operationQueue release], _operationQueue = nil; [super dealloc]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[NSOperationQueue cancelAllOperations]
[NSOperationQueue cancelAllOperations]会遍历queue中的所有operation,并逐个对operation调用-cancel函数。而-cancel函数所做的仅仅是将operation标记为cancelled,至于是否何时检查isCancelled属性并尽快停止运行是由各个operation自己决定的。比如:在-start的默认实现中(非并行时),在其开始之前会检查isCancelled属性。
// main.m #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; [operationQueue setMaxConcurrentOperationCount:1]; [operationQueue addOperationWithBlock:^{ for (int i=0; i<100; i++) { NSLog(@"%d", i); // will print 0~99 } }]; sleep(1); if ([operationQueue operationCount] > 0) { [operationQueue cancelAllOperations]; } [[NSRunLoop currentRunLoop] run]; } return 0; }
// main.m #import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init]; [operationQueue setMaxConcurrentOperationCount:1]; NSBlockOperation *operation = [[NSBlockOperation alloc] init]; [operation addExecutionBlock:^{ for (int i=0; i<100; i++) { if ([operation isCancelled]) { return ; } else { NSLog(@"%d", i); // will not print } } }]; sleep(1); if ([operationQueue operationCount] > 0) { [operationQueue cancelAllOperations]; } } return 0; }