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];
}];
}
}
持续完善……