// 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;
}