iOS 多執行緒之NSOperationQueue

joker_king發表於2018-12-20

NSOperationQueue和NSOperation

NSOperation

  • NSOperation類,在MVC中屬於M,是用來封裝單個任務相關的程式碼和資料的抽象類。
  • 因為它是抽象的,不能夠直接使用這個類,而是使用子類NSInvocationOperation或NSBlockOperation來實際執行任務。
  • NSOperation以及它的子類,只是一個操作,本身無主執行緒和子執行緒之分。可在任意執行緒中使用,通常NSOperationQueue結合使用。

NSInvocationOperation

  • NSInvocationOperationNSOperation的子類。
  • 封裝了執行操作的target和要執行的action
  • 如果任務不在佇列中,那麼就需要我們手動啟動任務。

使用NSInvocationOperation建立一個任務

NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc]initWithTarget:self 
selector:@selector(NSOperation) object:nil];
//手動啟動任務
[invocationOperation start];
複製程式碼

NSBlockOperation

  • NSBlockOperationNSOperation的子類
  • 封裝了需要執行的程式碼塊
  • 如果任務不在佇列中,那麼就需要我們手動啟動任務。

使用NSBlockOperation建立一個任務

NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
     NSLog(@"-             ----block%@",[NSThread currentThread]);
}];
[blockOperation start];
複製程式碼

NSOperationQueue

  • NSOperationQueue是操作佇列,它用來管理一組NSOperation物件的執行。
  • 其中NSOperation可以呼叫它在佇列中的優先順序(使用addDependency:設定依賴關係)在我們希望某幾個任務執行的時候有先後關係 ,我們就可以為任務新增依賴。不能互相新增依賴。
  • 通過設定最大併發數,讓一組任務可以有序的執行 。最大併發數的預設值為-1,意思為無限個。當最大併發數設定為1的時候可以讓一組任務可以有序的執行。
  • NSOperationQueue操作佇列,實現多執行緒的一種技術手段,thread需要我們手動的去管理記憶體,佇列不需要。thread每次只能開闢一個子執行緒,佇列可以排程,分配、管理多個執行緒。
  • NSOperationQueue佇列有兩種,一種是其他佇列,一種是主佇列。獲取主佇列的任務都是在主執行緒中執行的,其他佇列中的任務都是在子執行緒中執行的。

NSOperationQueue主佇列

建立任務並將任務新增進主佇列中

示例程式碼

- (void)mainQienestudy{
    NSOperationQueue *mainQuene = [NSOperationQueue mainQueue];
    NSBlockOperation *bloskOperation_0 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1--------%@",[NSThread currentThread]);
    }];
    NSBlockOperation *bloskOperation_1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2--------%@",[NSThread currentThread]);
    }];
    NSBlockOperation *bloskOperation_2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3--------%@",[NSThread currentThread]);
    }];
    //將任務新增到主佇列中
    [mainQuene addOperation:bloskOperation_0];
    [mainQuene addOperation:bloskOperation_1];
    [mainQuene addOperation:bloskOperation_2];
}
複製程式碼

NSOperationQueue其他佇列

建立任務並將任務新增進其他佇列中

示例程式碼

- (void)OperationQueueStudy{
//建立一個其他佇列,通過初始化方式建立的佇列只能是其他佇列
    NSOperationQueue *OtherQuene = [[NSOperationQueue alloc]init];
//佇列中只能新增任務
    NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@1",[NSThread currentThread]);
    }];
    NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@2",[NSThread currentThread]);
    }];
    NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@3",[NSThread currentThread]);
    }];
    NSBlockOperation *blockOperation4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@4",[NSThread currentThread]);
    }];
    NSBlockOperation *blockOperation5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"%@5",[NSThread currentThread]);
    }];
//希望某幾個任務執行的時候有先後關係 ,我們就可以為任務新增依賴。不能互相新增依賴。
//    [blockOperation1 addDependency:blockOperation5];
//通過設定最大併發數,讓一組任務可以有序的執行 。最大併發數的預設值為-1,意思為無限個。
    OtherQuene.maxConcurrentOperationCount = 1;
//將任務新增到佇列,在佇列中的任務不需要手動啟動。
    [OtherQuene addOperation:blockOperation1];
    [OtherQuene addOperation:blockOperation2];
    [OtherQuene addOperation:blockOperation3];
    [OtherQuene addOperation:blockOperation4];
    [OtherQuene addOperation:blockOperation5];
}
複製程式碼

總結

只要是新增進主佇列的任務,一定是在主執行緒中進行的,不管這個主佇列出現在哪裡。所以這也是一種從子佇列返回主佇列的方法,我們只需要在要返回主執行緒的子執行緒使用這個方法,就可以返回主佇列。

相關文章