一、使用NSOperation的子类来创建操作
1.NSInvocationOperation子类
//创建
NSInvocationOperation * opration = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task) object:nil];
[oprationstart];
当不使用NSOperationQueue,默认是在主线程中执行
2.NSBlockOperation子类
NSBlockOperation * operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"当前线程1= in %@",[NSThread currentThread]);
}];
[operationaddExecutionBlock:^{
NSLog(@"当前线程2= in %@",[NSThread currentThread]);
}];
[operationaddExecutionBlock:^{
NSLog(@"当前线程3= in %@",[NSThread currentThread]);
}];
[operationaddExecutionBlock:^{
NSLog(@"当前线程4= in %@",[NSThread currentThread]);
}];
[operationaddExecutionBlock:^{
NSLog(@"当前线程5= in %@",[NSThread currentThread]);
}];
[operationstart];
当只使用NSBlockOperation时,默认是在当前线程执行,如果通过operationAddExectionBlock追加操作,则所有操作会在不同线程中执行。
3.自定义继承NSOperation 如果以上两种不能满足需求,则可以通过继承NSOperation类,实现自定义操作。在自定义类中重写main方法,实现自定义的功能。使用时实例化该类即可。
二、NSOperationQueue
1.NSOperationQueue创建包含两种:主队列和自定义队列(非主队列)
NSOperationQueue * queue = [NSOperationQueue mainQueue];// 创建主队列
NSOperationQueue * queue = [[NSOperationQueue alloc]init];//自定义队列
可以使用addOperation添加已经创建的操作到队列中,也可以使用addOperationWithBlock创建操作并添加到队列中。将多个操作添加到队列中,是异步处理。
2.最大并发操作数
NSOperationQueue通过 maxConcurrentOperationCount设置最大并发操作数,当count为1时,是串行队列,但是并不意味着只有一个线程,就像GCD串行队列中不一定只有一个线程一样。最大并发数不可无限大,系统会限定一个最大并发数值,如果你的值大于这个值,则以系统为准。
3.添加操作依赖、移除依赖、
NSOperation可以通过addDependency设置依赖关系。
// 1.创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
// 2.创建操作
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 2; i++) {
[NSThread sleepForTimeInterval:2]; // 模拟耗时操作
NSLog(@"1---%@", [NSThread currentThread]); // 打印当前线程
}
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 2; i++) {
[NSThread sleepForTimeInterval:2]; // 模拟耗时操作
NSLog(@"2---%@", [NSThread currentThread]); // 打印当前线程
}
}];
// 3.添加依赖
[op2 addDependency:op1]; // 让op2 依赖于 op1,则先执行op1,在执行op2
// [op2 removeDependency:op1];//移除依赖关系
// 4.添加操作到队列中
[queue addOperation:op1];
[queue addOperation:op2];
4.NSOperation优先级
NSOperation提供了queuePriority优先级属性,是个枚举值。同一个队列中可设置操作的优先级。依赖关系优先于优先级
5.线程间的通信
通过[[NSOperationQueue mainQueue]addOperationWithBlock:^{
}];执行回到主线程的操作
三、NSOperation和NSOperationQueue中的常用方法
NSOperation常用方法:
1.- (BOOL)isFinished; 判断操作是否已经结束。
2.- (BOOL)isCancelled;判断操作是否已经标记为取消。
3.- (BOOL)isExecuting;判断操作是否正在在运行。
4.- (BOOL)isReady; 判断操作是否处于准备就绪状态,这个值和操作的依赖关系相关。
5.- (void)waitUntilFinished; 阻塞当前线程,直到该操作结束。可用于线程执行顺序的同步。
6.- (void)setCompletionBlock:(void (^)(void))block; completionBlock 会在当前操作执行完毕时执行 completionBlock。
7.- (void)addDependency:(NSOperation *)op; 添加依赖,使当前操作依赖于操作 op 的完成
8.- (void)removeDependency:(NSOperation *)op; 移除依赖,取消当前操作对操作 op 的依赖。
9.@property (readonly, copy) NSArray<NSOperation *> *dependencies; 在当前操作开始执行之前完成执行的所有操作对象数组。
NSOperationQueue常用属性和方法
1.取消/暂停/恢复操作
- (void)cancelAllOperations;可以取消队列的所有操作。
- (BOOL)isSuspended;判断队列是否处于暂停状态。 YES 为暂停状态,NO 为恢复状态。
- (void)setSuspended:(BOOL)b;可设置操作的暂停和恢复,YES 代表暂停队列,NO 代表恢复队列。
2.操作同步
- (void)waitUntilAllOperationsAreFinished;阻塞当前线程,直到队列中的操作全部执行完毕。
3.添加/获取操作`
- (void)addOperationWithBlock:(void (^)(void))block;向队列中添加一个 NSBlockOperation 类型操作对象。
4.- (void)addOperations:(NSArray *)ops waitUntilFinished:(BOOL)wait;向队列中添加操作数组,wait 标志是否阻塞当前线程直到所有操作结束
5.- (NSArray *)operations;当前在队列中的操作数组(某个操作执行结束后会自动从这个数组清除)。
6.- (NSUInteger)operationCount;当前队列中的操作数。
7.获取队列
+ (id)currentQueue;获取当前队列,如果当前线程不是在 NSOperationQueue 上运行则返回 nil。
8.+ (id)mainQueue;获取主队列。