多线程之NSOperation

NSOperation:面向对象的线程技术
不需要关心线程管理、数据同步的事情,可以把精力放在自己需要执行的操作上
面向对象

NSOperation中两个常用对象:
1.NSInvocationOperation
示例:

//定义操作队列
@property (nonatomic, strong) NSOperationQueue *queue;

- (void)operationLoad{
    for (UIImageView *imageView in self.imageViewSet) {
//        invocation
        NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(threadLoadImage:) object:imageView];
//        直接调用operation的start方法,是在主线程队列上运行的,不会开启新的线程
//        [operation start];
//        将invacation添加到队列,已添加到队列,就会开启新的线程执行任务
        [self.queue addOperation:operation];
    }
}

2.NSBlockOperation
定义完operation之后将操作添加到NSOperationQueue即可启动任务
示例:

- (void)operationLoad{
    for (UIImageView *imageView in self.imageViewSet) {
//        block
        NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
            [self operationLoadImage:imageView];
        }];
        [self.queue addOperation:operation];
    }
}

优点:
1.使用setMaxConcurrentOperationCount可以控制同时并发的线程数量

//  队列可以设置同时并发线程数量
    [self.queue setMaxConcurrentOperationCount:4];

2.使用addDependency可以添加依赖,从而控制线程执行顺序

- (void)operationDemo{
    NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"操作1:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"操作2:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"操作3:%@",[NSThread currentThread]);
    }];
/**
 * Dependency依赖
 * 可以多重依赖
 * 注意不要建立循环依赖
 */
//    operation2依赖于operation1
    [operation2 addDependency:operation1];
    [operation3 addDependency:operation2];
    
    [self.queue addOperation:operation1];
    [self.queue addOperation:operation2];
    [self.queue addOperation:operation3];
    
}

提示:要更新UI,需要使用[[NSOperationQueue mainQueue] addOperationWithBlock:^{}];在主队列更新UI

- (void)operationLoadImage:(UIImageView *)imageView{
    @autoreleasepool {
        NSLog(@"%@",[NSThread currentThread]);
        //        睡眠
        //        [NSThread sleepForTimeInterval:1.0f];
        
        NSInteger num = arc4random_uniform(17) + 1;
        NSString *imageName = [NSString stringWithFormat:@"NatGeo%02ld",(long)num];
//        在主线程队列上更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            imageView.image = [UIImage imageNamed:imageName];
        }];
    }
}

持续完善……

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容