天天看点

多线程之四:NSOperation与NSOperationQueue

1.NSOperationQueue:代表一个FIFO的队列,它负责管理系统提交的多个NSOperation,NSOperationQueue底层维护一个线程池,会按顺序启动线程来执行提交给该队列的NSOperation任务。

NSOperation:代表一个多线程任务。NSOperation还有NSInvocationOperation.NSBlockOperation两个子类。

NSOperation有两种使用方式:

方式1:开发者实现NSOperation的子类

方式2:直接使用NSInvocationOperation或NSBlockOperation子类。

2.使用NSBlockOperation子类

    queue = [[NSOperationQueue alloc]init];

    //设置该队列最大支持10个并发线程

    queue.maxConcurrentOperationCount = 10;

 NSString *url = @"http://www.crazyit.org/logo.jpg";

    //以传入的代码块作为执行体,创建NSOperation

    NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{

       //从网络获取数据

        NSData *data = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:url]];

        UIImage *image = [[UIImage alloc]initWithData:data];

        if (image!=nil) {

            //在主线程中执行updateUI方法

            [self performSelectorOnMainThread:@selector(updateUI:) withObject:imagewaitUntilDone:YES];

        }

        else

        {

            NSLog(@"下载图片出现错误");

        }

    }];

    [queue addOperation:operation];

3. 定义NSOperation子类

NSOperation一般不会直接拿来使用,而是选择创建它的子类,创建NSOperation的子类需要重写main方法。(写的方法似乎不会被调用,可以在init方法直接调用)

定义子类STDownOperation

//.m

- (id)initWithURL:(NSURL *)url imageView:(UIImageView *)iv

{

    self = [super init];

    if (self) {

        _imageView = iv;

        _url = url;

        [self main];

    }

    return self;

}

//重写main方法,该方法将作为线程执行体:为什么不执行?

- (void)main

{

    //从网络获取数据

    NSData *data = [[NSData alloc]initWithContentsOfURL:self.url];

    UIImage *image = [[UIImage alloc]initWithData:data];

    if (image!=nil) {

        //在主线程中更新UI

        [self performSelectorOnMainThread:@selector(updateUI:) withObject:imagewaitUntilDone:YES];

    }

    else

    {

        NSLog(@"下载图片出现错误");

    }

}

- (void)updateUI:(UIImage *)image

{

    self.imageView.image = image;

}

//.h

@property (nonatomic, strong)NSURL *url;

@property (nonatomic, strong)UIImageView *imageView;

- (id)initWithURL:(NSURL *)url imageView:(UIImageView *)iv;

然后调用该类

- (void)clicked:(UIButton *)sender

{

    NSString *url = @"http://www.crazyit.org/logo.jpg";

    STDownOperation *operation = [[STDownOperation alloc]initWithURL:[NSURLURLWithString:url] imageView:imageView];

    [queue addOperation:operation];

​}