不能直接使用NSOperation,而是使用系统定义的子类来完成实际任务
两个子类:NSInvocationOperation和 NSBlockOperation 他们只能执行一次任务,而且不能再次执行他,可以将它添加到一个操作队列中执行,这个可以用NSOperationQueue实现
NSOperation的创建方式,可以用定义好的两个子类创建
//第一种
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationAction1) object:nil];
[op1 start];
//第二种
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
[queue setSuspended:YES];//暂停任务
NSLog(@" op2 %@",[NSThread currentThread]);
}];
[op2 start];//线程开始
//第三种 :创建继承NSOperation的子类
//用子类创建的任务
BVOperation *op3 = [[BVOperation alloc]initWithBiock:^{
NSLog(@"op3 %@",[NSThread currentThread]);
}];
// [op3 start];
2.3 NSOperation和NSOperationQueue实现多线程的步骤:
1)先将需要执行的操作封装到一个NSOperation对象中
2)再将NSOperation对象添加到NSOperationQueue中 队列
3)系统会自动将NSOperationQueue中的NSOperation取出来
4)将取出的NSOperation封装的操作放到一条新线程中执行
// NSOperationQueue *queue = [[NSOperationQueue alloc]init];
//添加任务到任务队列
//[queue addOperation:op1];
或者初始化后添加一个数组,将需要的任务全部添加进去
// 添加多个任务到队列,bool值表示当前线程的其他任务执行完成,设置yes会导致卡死
// [queue addOperations:@[op1,op2,op3] waitUntilFinished:YES];
//创建一个隐式添加
// [queue addOperationWithBlock:^{
// NSLog(@"queue block %@",[NSThread currentThread]);
// }];
3.)NSOperation的执行顺序:
对于添加到队列中的任务,他们的执行顺序取决于两点:
1.首先看NSOperation是否已经准备好:是否准备好由对象的依赖关系确定
2.然后在根据所有的NSOperation的相对优先级确定
注意?:任务添加到队列中之后,绝对不要再修改对象的状态(各属性),因为nsoperation对象可能会在任何时候运行,所以可能会对其造成不利影响
3.1 nsoperation添加依赖关系 (不能创建循环依赖)
//添加依赖在任务添加到队列之前,但是添加依赖成功的前提是任务添加到队列中
op1依赖op2.
// [op1 addDependency:op2];
//
// [op1 addDependency:op3];
3.2 修改NSOperation的优先级 它是operation对象本身的一个属性(默认优先级为普通)
可以通过setQueuePriority:方法来提升或降低operation对象的优先级,只能应用于相同的queue中的operations。
注意:优先级不能替代依赖关系,优先级只是对准备好的operations确定执行顺序,先满足依赖关系,然后再根据优先级从准备好的操作中选择优先级高的执行。
#warning 设置最大并发数
[queue setMaxConcurrentOperationCount:1];//设置最大并发数的方法(NSInteger)
#warning 取消任务,注意,已经运行的任务无法停止
// [op2 cancel];//取消任务的方法
#warning 通过阻塞线程的方式实现同步
[queue addOperation:op1];
[op1 waitUntilFinished];
NSLog(@"øøøøøøøøøøøøøøøøøøøø");
[queue addOperation:op2];
[queue addOperation:op3];
#warning 暂停和继续
暂停一个queue不会导致正在执行的operation在任务的中途暂停,可以在添加到队列之前用[queue setSuspended:YES];//暂停任务 方法
注意:一定记得让其恢复继续执行
//设置一个延时
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[queue setSuspended:NO];
});