NSOperation分为三种:NSInvocationOperation、NSBlockOperation、NSOperation自定义
一、NSInvocationOperation讲解
1.不能开辟子线程的NSInvocationOperation
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest0) object:nil];
// 执行此操作
[operation start];
- (void ) invocationTest0 {
NSLog(@"invocationTest0===%@",[NSThread currentThread]);
}
结果为:invocationTest0===<NSThread: 0x28386a380>{number = 1, name = main}
由于没有把创建的操作添加到队列中,所以不具备开辟子线程的能力。
2.能开辟子线程的NSInvocationOperation
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest0) object:nil];
// 创建队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
- (void ) invocationTest0 {
NSLog(@"invocationTest0===%@",[NSThread currentThread]);
}
结果为:invocationTest0===<NSThread: 0x281094340>{number = 4, name = (null)}
由于创建了队列并把创建的操作添加到了队列中,所以具备了开辟新线程的能力
同时不需要操作执行start方法就可以自动执行。
二、NSBlockOperation讲解
1.不能开辟新线程的NSBlockOperation
// 创建方式一
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"userBlockOperation0==%@",[NSThread currentThread]);
}];
[operation start];
// 创建方式二
NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
[operation1 addExecutionBlock:^{
NSLog(@"userBlockOperation0addExecutionBlock==%@",[NSThread currentThread]);
}];
[operation1 start];
结果为:userBlockOperation0==<NSThread: 0x280c86380>{number = 1, name = main}
userBlockOperation0addExecutionBlock==<NSThread: 0x280c86380>{number = 1, name = main}
从结果可以看出,当NSBlockOperation不添加到队列中,直接进行start的时候,是不具有开辟新线程的能力的。
2.能开辟新线程的NSBlockOperation
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
// 我在当前的队列线程中,比如不添加相关队列,直接执行就是在主线程中的
NSLog(@"最大并发数可以控制我==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
// 设置最大并发数不可以控制我的,我是异步的,会开辟子线程,不需要添加到队列中
NSLog(@"block0==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block1==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block2==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block3==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block4==%@",[NSThread currentThread]);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation1];
结果:
最大并发数可以控制我==<NSThread: 0x282d8de40>{number = 4, name = (null)}
block0==<NSThread: 0x282dbcf80>{number = 5, name = (null)}
block1==<NSThread: 0x282d8de40>{number = 4, name = (null)}
block2==<NSThread: 0x282dbcf80>{number = 5, name = (null)}
block3==<NSThread: 0x282d81a80>{number = 6, name = (null)}
block4==<NSThread: 0x282d8de40>{number = 4, name = (null)}
从结果可以看出,当NSBlockOperation添加到队列中,具有开辟新线程的能力的。
三、添加依赖
1.NSInvocationOperation添加依赖
/// 加入到队列中,会创建子线程
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest0) object:nil];
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest1) object:nil];
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest2) object:nil];
// 添加依赖,前面的依赖后面的,就是先执行后面的
[operation1 addDependency:operation];
[operation addDependency:operation2];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
[queue addOperation:operation1];
[queue addOperation:operation2];
结果是:
invocationTest2===<NSThread: 0x281c5e540>{number = 6, name = (null)}
invocationTest0===<NSThread: 0x281c5e540>{number = 6, name = (null)}
invocationTest1===<NSThread: 0x281c5e540>{number = 6, name = (null)}
从结果可以看出,当Operation有依赖关系的时候,会先执行后面的操作。
2.NSBlockOperation添加依赖
// 创建要执行的任务
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"operation1==%@",[NSThread currentThread]);
}];
// 给对应的操作再添加任务
[operation1 addExecutionBlock:^{
NSLog(@"operation1_addExecutionBlock0==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"operation1_addExecutionBlock1==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"operation2==%@",[NSThread currentThread]);
}];
[operation2 addExecutionBlock:^{
NSLog(@"operation2_addExecutionBlock0==%@",[NSThread currentThread]);
}];
[operation2 addExecutionBlock:^{
NSLog(@"operation2_addExecutionBlock1==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"operation3==%@",[NSThread currentThread]);
}];
// 设置依赖,任务1依赖于任务二,任务二依赖于任务三,执行顺序是3、2、1
[operation1 addDependency:operation2];
[operation2 addDependency:operation3];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
结果是:
operation3==<NSThread: 0x282140500>{number = 4, name = (null)}
operation2==<NSThread: 0x282140500>{number = 4, name = (null)}
operation2_addExecutionBlock0==<NSThread: 0x282143640>{number = 5, name = (null)}
operation2_addExecutionBlock1==<NSThread: 0x28214c100>{number = 3, name = (null)}
operation1_addExecutionBlock1==<NSThread: 0x282143640>{number = 5, name = (null)}
operation1_addExecutionBlock0==<NSThread: 0x28214c100>{number = 3, name = (null)}
operation1==<NSThread: 0x282140500>{number = 4, name = (null)}
从结果来看NSBlockOperation添加依赖和NSInvocationOperation依赖一样,都是先执行后面的操作。但是如果某个操作右添加了相关的任务就,那么执行所有操作的顺序不变,每个操作中再添加的所有任务就是异步的。
四、设置最大操作并发数
1.NSInvocationOperation设置最大并发数
/// 加入到队列中,会创建子线程
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest0) object:nil];
NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest1) object:nil];
NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest2) object:nil];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperation:operation];
[queue addOperation:operation1];
[queue addOperation:operation2];
- (void ) invocationTest0 {
NSLog(@"invocationTest0===%@",[NSThread currentThread]);
}
结果是:
invocationTest0===<NSThread: 0x280f847c0>{number = 4, name = (null)}
invocationTest1===<NSThread: 0x280f847c0>{number = 4, name = (null)}
invocationTest2===<NSThread: 0x280f9ce00>{number = 6, name = (null)}
从结果看,当设置最大并发操作数量为1的时候,执行操作的顺序就是对应的操作添加到队列的顺序,这时就相当于添加了依赖。
当最大并发操作数量为大于1的时候,执行顺序就是会乱,同一时间会执行多个操作。
2.NSBlockOperation设置最大并发数
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"operation1==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block0==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block1==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block2==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block3==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block4==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
// 我在当前的队列线程中,比如不添加相关队列,直接执行就是在主线程中的
NSLog(@"operation2==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
// 我在当前的队列线程中,比如不添加相关队列,直接执行就是在主线程中的
NSLog(@"operation3==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
// 我在当前的队列线程中,比如不添加相关队列,直接执行就是在主线程中的
NSLog(@"operation4==%@",[NSThread currentThread]);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
结果是:
operation1==<NSThread: 0x2800e4b80>{number = 6, name = (null)}
block1==<NSThread: 0x2800e4740>{number = 7, name = (null)}
block2==<NSThread: 0x2800e4740>{number = 7, name = (null)}
block4==<NSThread: 0x2800de280>{number = 8, name = (null)}
block3==<NSThread: 0x2800e4740>{number = 7, name = (null)}
block0==<NSThread: 0x2800e4b80>{number = 6, name = (null)}
operation2==<NSThread: 0x2800e4b80>{number = 6, name = (null)}
operation3==<NSThread: 0x2800e4b80>{number = 6, name = (null)}
operation4==<NSThread: 0x2800e4b80>{number = 6, name = (null)}
从结果可以看出,当设置最大并发操作数量为1的时候,执行操作的顺序就是对应的操作添加到队列的顺序,但是每个操作中添加的任务就是异步的了(没有顺序)。
五、设置优先级
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"operation1==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block0==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block1==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block2==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block3==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
NSLog(@"block4==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
sleep(2);
// 我在当前的队列线程中,比如不添加相关队列,直接执行就是在主线程中的
NSLog(@"operation2==%@",[NSThread currentThread]);
}];
operation2.queuePriority = NSOperationQueuePriorityVeryHigh;
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
// 我在当前的队列线程中,比如不添加相关队列,直接执行就是在主线程中的
NSLog(@"operation3==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
// 我在当前的队列线程中,比如不添加相关队列,直接执行就是在主线程中的
NSLog(@"operation4==%@",[NSThread currentThread]);
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation1];
[queue addOperation:operation2];
[queue addOperation:operation3];
[queue addOperation:operation4];
结果是:
operation1==<NSThread: 0x2817edd40>{number = 3, name = (null)}
block0==<NSThread: 0x2817edd40>{number = 3, name = (null)}
operation3==<NSThread: 0x281799040>{number = 6, name = (null)}
block1==<NSThread: 0x2817edd40>{number = 3, name = (null)}
block2==<NSThread: 0x281799040>{number = 6, name = (null)}
block3==<NSThread: 0x2817edd40>{number = 3, name = (null)}
block4==<NSThread: 0x281799040>{number = 6, name = (null)}
operation4==<NSThread: 0x2817b2840>{number = 4, name = (null)}
operation2==<NSThread: 0x2817b5300>{number = 5, name = (null)}
从结果看出,给操作设置优先级只是说此操作执行的顺友优先级排在前面,但是具体执行完毕后是否在最前面还是决定于操作内任务的多少。
六、队列的挂起和取消
操作已经被调度的时候是不能挂起和取消的。
取消操作其实就是移除了此操作
网友评论