iOS中另外一种多线程实现方式NSOperation

NSOperation是一个抽象类,不能直接使用,一般采用下面三种方式:
1. 自定义子类继承
2. 已有子类NSInvocationOperation:执行一个封装好的操作,可传参
3. 已有子类NSBlockOperation:执行一个或多个block
当然还要配合队列NSOperationQueue才能真正实现多线程。
(一)、自定义继承
继承时需要注意的点很多,这里简单列几点:
1. 继承子类时要考虑NSOperation只能执行一次,多次执行会出错
2. 取消操作相当于这个operation完成了,这在设置一些依赖时需要特别注意。但是取消之后是否继续执行下一个operation开发者可以自己控制。
3. 可以对当前状态比如是否取消,是否结束,是否准备好进行KVO监控,但最好不要在主界面中执行这样的绑定监控。
4. 如果自己在子类中添加了属性,最好支持KVO
5. 子类中实现的方法要考虑多线程访问的问题。
6. 其他的可以参见NSOperation的注释,比较多,用的话最好还是通读一些。
例如:
@interface TestOperation : NSOperation
@end
@implementation TestOperation
- (void)main {
NSLog(@”Test Operation”);
}
@end
TestOperation *operation = [[TestOperation alloc] init];
NSOperationQueue *q = [[NSOperationQueue alloc] init];
[q addOperation:operation ];
(二)、NSInvocationOperation
主要用于执行一个指定的函数,同时也可以指定目标和参数。
例:
NSInvocationOperation *operation=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(test) object:nil];
//开始执行
[operation start];

-(void)test
{
NSLog(@”test–%@”,[NSThread currentThread]);
}
但是执行之后会发现,并未开启新的线程,在同一线程中执行。也就是说需要添加到队列中才能开启子线程执行。
NSOperationQueue *q = [[NSOperationQueue alloc] init];
[q addOperation:operation ]; //add执行完后,就开始运行了
(三)、NSBlockOperation
主要是用于在子线程执行一个或多个block,具体使用形式如下:
NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
//……
}];

//添加block
[operation addExecutionBlock:^{
//….
}];
//设置完成之后要执行的操作
[operation setCompletionBlock:^{
//….
}]; //一般在operation对应的线程执行,若有多个block,会创建多个子线程,则随机找一个子线程执行该block
例:
NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{
NSLog(@”test–%@”,[NSThread currentThread]);
}];
//开启执行
[operation start];
上述操作仍然在调用的线程执行,并未开启新的线程。
如果在start之前,添加多个block,如下
[operation addExecutionBlock:^{
NSLog(@”test1–%@”,[NSThread currentThread]);
}];
[operation addExecutionBlock:^{
NSLog(@”test2–%@”,[NSThread currentThread]);
}];
//再执行start
[operation start];
可以发现,三个block中会有一个在原有线程执行,而其他两个却开辟了新的线程,也就是说当block个数大于1时,即使不添加到队列也会开辟新线程异步进行。三个block是并行进行的。
(四)、NSOperationQueue
有了上述三个子类,就可以将子类的实例添加到NSOperationQueue中进行统一管理,包括添加,取消队列运行,暂停,设置依赖,设置并发的线程数等。
也可以在主线程队列中添加block或者NSOperation子类
[[NSOpeationQueue mainQueue] addOperationWithBlock: ^{
}];
[[NSOperationQueue mainQueue] addOperation:operation];

有一点需要注意,添加到队列的顺序并不能保证执行的顺序,虽然串行从队列取出,但是一旦取出后各个任务可能并行执行,至于执行的顺序可以靠设置依赖来决定。设置依赖时注意不要循环依赖
[operation3 addDependency:operation1];
[operation1 addDependency:operation2];

并且设置依赖一定要在添加到队列之前,否则不起作用。

一般将并发的线程数设置为5以内,都在可能导致CPU消耗过多,影响UI体验。
- (void)setMaxConcurrentOperationCount:(NSInteger)cnt;

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

perman_scut

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值