现在的位置: 首页 > 综合 > 正文

NSOperation/NSOperationQueue small demo

2013年08月13日 ⁄ 综合 ⁄ 共 3701字 ⁄ 字号 评论关闭

//  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]

 http://desheng.me/2010/10/05/%E5%AF%B9-nsoperationqueue-cancelalloperations-%E7%9A%84%E7%90%86%E8%A7%A3/

http://stackoverflow.com/questions/12660706/nsoperation-cancelalloperations-does-not-stop-the-operation

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

抱歉!评论已关闭.