1.NSOperation是iOS中多线程操作的一种方式之一,NSOperation是一个抽象类,是任务的意思,是线程执行的最小单位,任务需要开辟线程去执行,但是NSOperation本身是不能开辟线程的,而是有任务所在的队列(NSOperationQueue)去开辟
2.NSOperationQueue :线程队列,线程池,它是管理线程的开辟、执行、销毁等操作
3.NSOperationQueue中的任务是并行执行的
系统提供的队列
主队列:主线程所在的队列,叫主队列
获取主队列:在主队列中添加的任务最主要是UI刷新相关的,而且是不耗时的任务
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
[mainQueue addOperationWithBlock:^{
NSLog(@"在主线程队列中添加任务");
}];
创建普通的线程队列:管理任务(一个任务会被分配到一个线程上执行)执行的对象
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
注意:实际工作中,并不适用NSOperation类的对象,而是使用它的子类NSInvocationOperation,
创建调用任务
(1)第一种创建方式:
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(method1:) object:@10];
参数一:执行任务的对象,
参数二:要执行的任务(方法)
参数三:执行任务时所携带的参数
将任务添加到线程队列中,由队列去开辟线程、执行任务、任务结束之后回收线程
线程队列中的线程是可以被复用,当去往队列中添加任务时,队列会先去查找是否有空闲的线程,如果有,就将任务放到空闲线程上执行,如果没有会开辟新的线程去执行任务(在线程队列所允许的最大线程数范围内)
指定最大线程数:如果为-1 时,是一个很大的数,当前系统能够允许执行的最大线程数
queue.maxConcurrentOperationCount = -1;
[queue addOperation:op1];
(2)创建NSInvocationOperation的第二种方式:
NSMethodSignature:方法指定对象,对象中包含的信息,1.要执行的Method属于哪个类,2.调用的方法名字,3.执行这个方法的对象,4.执行方法时携带的参数
```
//指定要执行的方法所在的类,同时指定要执行的方法名
NSMethodSignature *sig = [Person instanceMethodSignatureForSelector:@selector(eat:drink:)];
//得到执行对象 NSInvocation
NSInvocation *invo = [NSInvocation invocationWithMethodSignature:sig];
//创建执行方法的对象
Person *p = [[Person alloc]init];
//指定执行任务的对象
[invo setTarget:p];
//指定执行的方法
[invo setSelector:@selector(eat:drink:)];
//指定执行任务携带的参数
NSString *food = @"切糕";
NSString *drinking = @"优乐美";
//设置参数时,下标从2开始,因为0和1分别被target 和selector占用
[invo setArgument:&food atIndex:2];
[invo setArgument:&drinking atIndex:3];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithInvocation:invo];
//添加到队列中
[queue addOperation:op2];
###### (3) 创建任务的第三中方式
[queue addOperationWithBlock:^{
NSLog(@"添加block任务");
//将你要执行的任务添加在这个block中
}];
//指定任务的依赖关系
NSInvocationOperation *op3 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(method3:) object:@10];
NSInvocationOperation *op4 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(method4:) object:@10];
//添加依赖,前者依赖于后者,需要后者执行结束之后,才可以开始执行前者
[op3 addDependency:op4];
//添加任务到队列中
[queue addOperation:op3];
[queue addOperation:op4];
}
-(void)method4:(NSNumber *)number
{
NSInteger i = number.integerValue;
while (i--) {
sleep(1);//休眠1秒
NSLog(@"任务4");
}
}
-(void)method3:(NSNumber *)number
{
NSInteger i = number.integerValue;
while (i--) {
sleep(1);//休眠1秒
NSLog(@"任务3");
}
}
-(void)method1:(NSNumber *)number
{
NSInteger i = number.integerValue;
while (i--) {
sleep(1);//休眠1秒
NSLog(@"任务1");
}
}