NSOperation

NSOperation的使用

NSOperation是個(gè)抽象類,并不具備封裝操作的能力,必須使用它的子類,使用NSOperation子類的方式有3種

  • NSBlockOperation
     //1. 封裝任務(wù)
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{      
        NSLog(@"1---%@", [NSThread currentThread]);
    }];
    //2.追加其它任務(wù)
    //注意: 在沒(méi)有隊(duì)列的情況下, 如果給BlockOperation追加其它任務(wù), 那么其它任務(wù)會(huì)在子線程中執(zhí)行
    [op1 addExecutionBlock:^{
        NSLog(@"2---%@", [NSThread currentThread]);
    }];
    [op1 addExecutionBlock:^{
        NSLog(@"3---%@", [NSThread currentThread]);
    }];
    //3.啟動(dòng)任務(wù)
    [op1 start];
  • 注意:
    默認(rèn)情況下,調(diào)用了start方法后并不會(huì)開(kāi)一條新線程去執(zhí)行操作,而是在當(dāng)前線程同步執(zhí)行操作,只有將NSOperation放到一個(gè)NSOperationQueue中,才會(huì)異步執(zhí)行操作

  • NSInvocationOperation

    //1.封裝任務(wù)
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run) object:nil];
    //2.要想執(zhí)行任務(wù)必須調(diào)用start
    [op1 start];
    
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(run2) object:nil];
    [op2 start];
}
- (void)run
{
    NSLog(@"%@", [NSThread currentThread]);
}
- (void)run2
{
    NSLog(@"%@", [NSThread currentThread]);
}
  • 自定義NSOperation
    自定義NSOperation的步驟:
    自定義一個(gè)繼承自NSOperation的子類,并重寫(xiě)- (void)main方法,在里面實(shí)現(xiàn)想執(zhí)行的任務(wù).
    只要將任務(wù)添加到隊(duì)列中, 那么隊(duì)列在執(zhí)行自定義任務(wù)的時(shí)候,就會(huì)自動(dòng)調(diào)用main方法
    //1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
     //2.創(chuàng)建任務(wù)
     //自定義任務(wù)的好處: 提高代碼的復(fù)用性
    YFYOperation *op1 = [[YFYOperation alloc] init];
    YFYOperation *op2 = [[YFYOperation alloc] init];
    
     //3.添加任務(wù)到隊(duì)列
    [queue addOperation:op1];
    [queue addOperation:op2];
  • 重寫(xiě)- (void)main方法的注意點(diǎn):
    自己創(chuàng)建自動(dòng)釋放池(因?yàn)槿绻钱惒讲僮?,無(wú)法訪問(wèn)主線程的自動(dòng)釋 放池)
    經(jīng)常通過(guò)- (BOOL)isCancelled方法檢測(cè)操作是否被取消,對(duì)取消做出響應(yīng)

NSOperationQueue

  • NSOperationQueue的作用
    NSOperation可以調(diào)用start方法來(lái)執(zhí)行任務(wù),但默認(rèn)是同步執(zhí)行的,如果將NSOperation添加到NSOperationQueue(操作隊(duì)列)中,系統(tǒng)會(huì)自動(dòng)異步執(zhí)行NSOperation中的操作
  • NSOperationQueue與NSBlockOperation
    //1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    //2.創(chuàng)建任務(wù)
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1 == %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2 == %@", [NSThread currentThread]);
    }];
  [queue addOperationWithBlock:^{
        NSLog(@"3 == %@", [NSThread currentThread]);
    }];
/*如果是使用block來(lái)封裝任務(wù), 那么有一種更簡(jiǎn)便的方法,只要利用隊(duì)列調(diào)用addOperationWithBlock:方法, 系統(tǒng)內(nèi)部會(huì)自動(dòng)封裝成一個(gè)NSBlockOperation,然后再添加到隊(duì)列中*/
  // 3.添加任務(wù)到隊(duì)列
    [queue addOperation:op1];
    [queue addOperation:op2];
  • NSOperationQueue與 NSInvocationOperation
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
     //2.創(chuàng)建任務(wù)
     //只要是自己創(chuàng)建的隊(duì)列, 就會(huì)在子線程中執(zhí)行,而且默認(rèn)就是并發(fā)執(zhí)行
    NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download1) object:nil];
    NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(download2) object:nil];
    //3.添加任務(wù)到隊(duì)列中,只要將任務(wù)添加到隊(duì)列中, 隊(duì)列會(huì)自動(dòng)調(diào)用start
    [queue addOperation:op1];
    [queue addOperation:op2];
- (void)download1
{
    NSLog(@"1 == %@", [NSThread currentThread]);
}
- (void)download2
{
    NSLog(@"2 == %@", [NSThread currentThread]);
}

最大并發(fā)數(shù)

  • 什么是并發(fā)數(shù)?
    同時(shí)執(zhí)行的任務(wù)數(shù),比如,同時(shí)開(kāi)3個(gè)線程執(zhí)行3個(gè)任務(wù),并發(fā)數(shù)就是3

  • 最大并發(fā)數(shù)的相關(guān)方法:
    - (NSInteger)maxConcurrentOperationCount;
    - (void)setMaxConcurrentOperationCount:(NSInteger)cnt;

  • 自己創(chuàng)建的隊(duì)列默認(rèn)是并發(fā), 如果設(shè)置
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    queue.maxConcurrentOperationCount = 1;//就是串行

  • 注意: 不能設(shè)置為0, 如果設(shè)置為0就不執(zhí)行任務(wù),
    默認(rèn)情況下maxConcurrentOperationCount = -1
    在開(kāi)發(fā)中并發(fā)數(shù)最多盡量不要超過(guò)5~6條

隊(duì)列的取消、暫停、恢復(fù)

  • 只要設(shè)置隊(duì)列的suspended為YES, 那么就會(huì)暫停隊(duì)列中其它任務(wù)的執(zhí)行
    self.queue.suspended = YES;
    也就是說(shuō)不會(huì)再繼續(xù)執(zhí)行沒(méi)有執(zhí)行到得任務(wù)
  • 注意: 設(shè)置為暫停之后, 不會(huì)立即暫停,會(huì)繼續(xù)執(zhí)行當(dāng)前正在執(zhí)行的任務(wù), 直到當(dāng)前任務(wù)執(zhí)行完畢, 就不會(huì)執(zhí)行下一個(gè)任務(wù)了,也就是說(shuō), 暫停其實(shí)是暫停下一個(gè)任務(wù), 而不能暫停當(dāng)前任務(wù)
  • 注意: 暫停是可以恢復(fù)的,只要設(shè)置隊(duì)列的suspended為NO, 那么就會(huì)恢復(fù)隊(duì)列中其它任務(wù)的執(zhí)行
  • 取消隊(duì)列中所有的任務(wù)的執(zhí)行
    [self.queue cancelAllOperations];
    取消和暫停一樣, 是取消后面的任務(wù), 不能取消當(dāng)前正在執(zhí)行的任務(wù)
  • 注意: 取消是不可以恢復(fù)的

操作依賴

  • NSOperation之間可以設(shè)置依賴來(lái)保證執(zhí)行順序,比如一定要讓操作A執(zhí)行完后,才能執(zhí)行操作B,可以這么寫(xiě)
    [operationB addDependency:operationA]; // 操作B依賴于操作A
  • 注意:不能相互依賴,比如A依賴B,B依賴A.
  • 可以在不同queue的NSOperation之間創(chuàng)建依賴關(guān)系
    // 1.創(chuàng)建隊(duì)列
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    NSOperationQueue *queue2 = [[NSOperationQueue alloc] init];

    // 2.創(chuàng)建任務(wù)
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"1-------%@", [NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"2-------%@", [NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"3-------%@", [NSThread currentThread]);
    }];
    NSBlockOperation *op4 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"4-------%@", [NSThread currentThread]);
        for (int i = 0; i < 1000; i++) {
            NSLog(@"%i", i);
        }
    }];
    NSBlockOperation *op5 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"5-------%@", [NSThread currentThread]);
    }];
    // 3.添加依賴
    [op5 addDependency:op1];
    [op5 addDependency:op2];
    [op5 addDependency:op3];
    [op5 addDependency:op4];
    // 4.監(jiān)聽(tīng)op4什么時(shí)候執(zhí)行完畢
    op4.completionBlock = ^{
        NSLog(@"op4中所有的操作都執(zhí)行完畢了");
    };
   // 5.添加任務(wù)到隊(duì)列
    [queue addOperation:op1];
    [queue addOperation:op2];
    [queue2 addOperation:op3];
    [queue2 addOperation:op4];
    [queue addOperation:op5];
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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