简介
iOS的多线程api一共有4套,从底层往上,分别是:
- p_thread :iOS基于unix操作系统,遵循POSIX标准,因此,最底层的多线程接口就是p_thread了。
- NSThread:基本上可以看成是p_thead的封装。
- GCD:可以理解为一种线程池化技术的实现。
- NSOperaion:GCD的封装,使用面向对象的方式管理任务和线程,提供了一些方便的api,代码可读性更高。
一:NSOperation
为什么要使用 NSOperation、NSOperationQueue?
- 可添加完成的代码块,在操作完成后执行。
- 添加操作之间的依赖关系,方便的控制执行顺序。
- 设定操作执行的优先级。
- 可以很方便的取消一个操作的执行。
- 使用 KVO 观察对操作执行状态的更改:isExecuteing、isFinished、isCancelled
1:NSOpration
基本使用
NSOperation 表示任务,它本身是一个抽象类,如果要封装操作,需要使用它的两个子类,NSInvocationOperation 和 NSBlockOperation ,其中 NSInvocationOperation 使用SEL的方式执行任务,而NSBlockOperation则通过block执行任务。
- (void)useBlockOperation{
NSBlockOperation* op = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"Invocation operation finished %@",[NSThread currentThread]);
}];
[op start];
}
- (void)useInvocationOperation{
NSInvocationOperation* op = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(invocationRun)
object:nil];
[op start];
}
-(void)invocationRun{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"Invocation operation finished %@",[NSThread currentThread]);
}
operation 作为任务,默认并不会开辟更多的线程,因此在哪个线程调用start,就在哪个线程执行。
但是,如果给 NSBlockOperation添加多个任务,新添加的任务会开辟其他线程,也可以自定义并发的NSOperation,但个人不是太建议这么用,并发就应该交给 NSOperationQueue 。
- (void)useBlockOperation{
NSBlockOperation* op = [NSBlockOperation blockOperationWithBlock:^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"Invocation operation finished %@",[NSThread currentThread]);
}];
//这个新添加的任务会开辟新的线程(这个估计是苹果为了方便做的api,后续讨论队列时,不包括这种情况)
[op addExecutionBlock:^{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"Invocation operation finished %@",[NSThread currentThread]);
}];
[op start];
}
自定义NSOperation的子类
我们也可以自己定义NSOpetaion的子类,好处是在子类中,可以使用成员变量来保存函数执行的一些结果,在涉及某些递归函数或者函数调用比较复杂时,定义子类会比较好用。
使用方法比较简单,继承NSOperation后,重写main方法就好。
@interface TTOperation : NSOperation{
}
@end
@implementation TTOperation
-(void)main{
[NSThread sleepForTimeInterval:1.0];
NSLog(@"tt operation finished %@",[NSThread currentThread]);
}
@end
2:NSOperatoinQueue
队列有两种:
主队列:所有操作都会放到主线程串行执行。
自定义队列:放到子队列执行,可以串行,也可以并行。
默认创建的队列是并行的,代码如下:
- (void)addOperationToQueue {
// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 添加任务
// 添加 NSInvocationOperation
NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationRun) object:nil];
// 添加 NSBlockOperation
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 2; i++) {
[NSThread sleepForTimeInterval:0.5];
NSLog(@"block operation finished 3 %@",[NSThread currentThread]);
}
}];
// 使用快捷添加方式
[queue addOperationWithBlock:^{
[NSThread sleepForTimeInterval:0.5