1. 程式人生 > >多執行緒程式設計-003-NSOPeration

多執行緒程式設計-003-NSOPeration

NSOPeration  [NSOperationQueue addOperation]

NSOPeration:將“操作”新增到“佇列”。GCD:將任務新增到佇列

NSOPeration抽象類 對GCD面向物件的封裝,特點:不能直接使用

目的:定義子類共有的屬性和方法.

子類:NSInvocationOperationNSBlockOperation

 NSThread -> pthread   佇列:GCD 併發佇列

NSOperation -> GCD   操作:非同步執行任務

//NSOperation 和  GCD 對比:
 //GCD 在 iOS 4.0 推出,針對多核處理器優化的併發技術,是C語言的
-將任務(block)新增到佇列 (序列、並行、主佇列、全域性佇列),並且要指定任務的同步、非同步; -執行緒間的通訊 dispatch_get_main_queue() -提供了一些 NSOperation 不具備的功能: 一次執行、 -延遲執行 、-排程組(NSoperation 也可以做到,但有點兒麻煩) // NSOperation 在 iOS 2.0; 蘋果推出了GCD後,對NSOperation 進行了重寫 -將操作[非同步執行的任務新增到併發佇列],就會立刻非同步執行 -提供了一些 GCD實現起來比較麻煩的功能 【下載】
-最大併發數 -佇列的暫停、繼續 -取消所有執行緒 -執行緒依賴(執行緒A 的執行 必須依賴執行緒B)(GCD 同步實現!)

NSInvocationOperation//將操作新增到佇列 

    NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage:) object:@"Invocation"];
    //會在當前執行緒執行排程方法
    //[op start];主執行緒
    //佇列
    NSOperationQueue * q = [[NSOperationQueue alloc] init];
    //將操作新增到佇列--會自動非同步執行排程方法
    [q addOperation:op ];//downImage為子執行緒

NSBlockOperation//將操作新增到佇列  

 //1.佇列
    NSOperationQueue * q = [[NSOperationQueue alloc] init];
    for (int i = 0; i<10; i++) {
        NSBlockOperation * op = [NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"---%@ -- %d",[NSThread currentThread],i);//執行順序和開執行緒數不固定
        }];
        //操作新增到佇列
        [q addOperation:op];
    }
      簡便方法:
          NSOperationQueue * q = [[NSOperationQueue alloc] init];
    for (int i = 0; i<10; i++) {
        [q addOperationWithBlock:^{
            NSLog(@"---%@ -- %d",[NSThread currentThread],i);
        }];
    }

③全域性佇列

@property (nonatomic, strong) NSOperationQueue * opQueue ;//直接新增任務
    for (int i = 0; i<10; i++) {
        [self.opQueue addOperationWithBlock:^{
            NSLog(@"---%@ -- %d",[NSThread currentThread],i);
        }];
    }
    //blockOperation
    NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
         NSLog(@"---BlockOperation%@ -- %d",[NSThread currentThread],100);
    }];
    [self.opQueue addOperation:op1];
    //invocation
    NSInvocationOperation * op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downImage:) object:@(101)];
    [self.opQueue addOperation:op2];

迴歸主執行緒

     [self.opQueue addOperationWithBlock:^{
        NSLog(@"%@",[NSThread currentThread]);
        //主執行緒
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"Main Thread %@",[NSThread currentThread]);
        }];
    }];

設定最大併發數(maxConcurrentOPerationCount)

//設定同時最大的併發運算元量
    self.opQueue.maxConcurrentOperationCount = 2;//一次最多開兩個
    //執行緒的銷燬原理 : A,B,C; 當A使用完之後,先把A回收到執行緒池,此時無法使用A,所以需要新開啟一個執行緒 
    //20 檔案? 20 執行緒?   //Wifi : 5-6   //流量:2-3
       for (int i = 0; i<20; i++) {
        [self.opQueue addOperationWithBlock:^{
            [NSThread sleepForTimeInterval:1.0];
            NSLog(@"---%@ -- %d",[NSThread currentThread],i);
        }];
    }

設定佇列的暫停和繼續(suspended)

//當掛起佇列的時候,正在執行的操作是不被掛起!就緒狀態的佇列才會被掛起
//suspended : 決定佇列的暫停和繼續
operationCount: 佇列中的運算元
- (IBAction)pause:(id)sender {
    //判斷佇列是否掛起
    if (self.opQueue.isSuspended) {
        NSLog(@"繼續 %tu",self.opQueue.operationCount);
        self.opQueue.suspended = NO;
    }else {
        NSLog(@"暫停 %tu",self.opQueue.operationCount);
        self.opQueue.suspended = YES;
    }
}

⑦取消所有操作(cancelAllOperations)

 - (IBAction)cancelAll:(id)sender {
    NSLog(@"取消所有操作!");
    [self.opQueue cancelAllOperations];//此時點選 暫停、繼續無法響應 :銷燬所有任務 operationCount=0
    //必須重新新增任務才可以使用暫停和繼續
}

⑧提供依賴關係(addDependency)

- (void)dependency {
    /**
     * 下載、解壓、通知使用者
     */
    //1.下載
    NSBlockOperation * op1 = [NSBlockOperation blockOperationWithBlock:^{
        [NSThread sleepForTimeInterval:3.0];
        NSLog(@"下載--%@ ",[NSThread currentThread]);
    }];
    //2.解壓
    NSBlockOperation * op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"解壓--%@ ",[NSThread currentThread]);
    }];
    //3.通知使用者
    NSBlockOperation * op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"通知使用者--%@ ",[NSThread currentThread]);
    }];
    NSLog(@"Come here");
    //NSOperation 提供依賴關係
    [op2 addDependency:op1];
    [op3 addDependency:op2];
    //[op1 addDependency:op3];//迴圈依賴 此時佇列不執行工作,也不會崩潰
    //新增佇列
    [self.opQueue addOperations:@[op1,op2] waitUntilFinished:YES];// YES在所有任務都完成後才會走Come here.
    //在主執行緒上通知使用者
    [[NSOperationQueue mainQueue] addOperation:op3];
    NSLog(@"Come here");
}