NSOperation分為三種:NSInvocationOperation、NSBlockOperation、NSOperation自定義
一、NSInvocationOperation講解
1.不能開辟子線程的NSInvocationOperation
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest0) object:nil];
// 執(zhí)行此操作
[operation start];
- (void ) invocationTest0 {
NSLog(@"invocationTest0===%@",[NSThread currentThread]);
}
結果為:invocationTest0===<NSThread: 0x28386a380>{number = 1, name = main}
由于沒有把創(chuàng)建的操作添加到隊列中,所以不具備開辟子線程的能力。
2.能開辟子線程的NSInvocationOperation
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(invocationTest0) object:nil];
// 創(chuàng)建隊列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
- (void ) invocationTest0 {
NSLog(@"invocationTest0===%@",[NSThread currentThread]);
}
結果為:invocationTest0===<NSThread: 0x281094340>{number = 4, name = (null)}
由于創(chuàng)建了隊列并把創(chuàng)建的操作添加到了隊列中,所以具備了開辟新線程的能力
同時不需要操作執(zhí)行start方法就可以自動執(zhí)行。
二、NSBlockOperation講解
1.不能開辟新線程的NSBlockOperation
// 創(chuàng)建方式一
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"userBlockOperation0==%@",[NSThread currentThread]);
}];
[operation start];
// 創(chuàng)建方式二
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:^{
// 我在當前的隊列線程中,比如不添加相關隊列,直接執(zhí)行就是在主線程中的
NSLog(@"最大并發(fā)數(shù)可以控制我==%@",[NSThread currentThread]);
}];
[operation1 addExecutionBlock:^{
// 設置最大并發(fā)數(shù)不可以控制我的,我是異步的,會開辟子線程,不需要添加到隊列中
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];
結果:
最大并發(fā)數(shù)可以控制我==<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添加依賴
/// 加入到隊列中,會創(chuàng)建子線程
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];
// 添加依賴,前面的依賴后面的,就是先執(zhí)行后面的
[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有依賴關系的時候,會先執(zhí)行后面的操作。
2.NSBlockOperation添加依賴
// 創(chuàng)建要執(zhí)行的任務
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依賴于任務二,任務二依賴于任務三,執(zhí)行順序是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依賴一樣,都是先執(zhí)行后面的操作。但是如果某個操作右添加了相關的任務就,那么執(zhí)行所有操作的順序不變,每個操作中再添加的所有任務就是異步的。
四、設置最大操作并發(fā)數(shù)
1.NSInvocationOperation設置最大并發(fā)數(shù)
/// 加入到隊列中,會創(chuàng)建子線程
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)}
從結果看,當設置最大并發(fā)操作數(shù)量為1的時候,執(zhí)行操作的順序就是對應的操作添加到隊列的順序,這時就相當于添加了依賴。
當最大并發(fā)操作數(shù)量為大于1的時候,執(zhí)行順序就是會亂,同一時間會執(zhí)行多個操作。
2.NSBlockOperation設置最大并發(fā)數(shù)
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:^{
// 我在當前的隊列線程中,比如不添加相關隊列,直接執(zhí)行就是在主線程中的
NSLog(@"operation2==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
// 我在當前的隊列線程中,比如不添加相關隊列,直接執(zhí)行就是在主線程中的
NSLog(@"operation3==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
// 我在當前的隊列線程中,比如不添加相關隊列,直接執(zhí)行就是在主線程中的
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)}
從結果可以看出,當設置最大并發(fā)操作數(shù)量為1的時候,執(zhí)行操作的順序就是對應的操作添加到隊列的順序,但是每個操作中添加的任務就是異步的了(沒有順序)。
五、設置優(yōu)先級
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);
// 我在當前的隊列線程中,比如不添加相關隊列,直接執(zhí)行就是在主線程中的
NSLog(@"operation2==%@",[NSThread currentThread]);
}];
operation2.queuePriority = NSOperationQueuePriorityVeryHigh;
NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
// 我在當前的隊列線程中,比如不添加相關隊列,直接執(zhí)行就是在主線程中的
NSLog(@"operation3==%@",[NSThread currentThread]);
}];
NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
// 我在當前的隊列線程中,比如不添加相關隊列,直接執(zhí)行就是在主線程中的
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)}
從結果看出,給操作設置優(yōu)先級只是說此操作執(zhí)行的順友優(yōu)先級排在前面,但是具體執(zhí)行完畢后是否在最前面還是決定于操作內(nèi)任務的多少。
六、隊列的掛起和取消
操作已經(jīng)被調(diào)度的時候是不能掛起和取消的。
取消操作其實就是移除了此操作