NSOperation

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)度的時候是不能掛起和取消的。
取消操作其實就是移除了此操作

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容