iOS多線程詳細(xì)說(shuō)明(NSOperation篇)

上一篇文章我們已經(jīng)了解過(guò)了什么是多線程,以及GCD的一些使用方法,下面繼續(xù)介紹另外一種iOS中實(shí)現(xiàn)多線程的方法NSOperation。
在學(xué)習(xí)這個(gè)類之前,我們還是需要知道幾個(gè)關(guān)鍵詞:

  • 1.任務(wù) : 就是你的具體操作,比如你要上傳照片、讀寫(xiě)數(shù)據(jù)庫(kù)等等,都可以視為任務(wù)
  • 2.隊(duì)列 : 隊(duì)列就是規(guī)定這個(gè)任務(wù)是怎么執(zhí)行的,是串行,還是并行
  • 3.線程:這個(gè)之前已經(jīng)介紹過(guò)了,這里就不多多介紹,想了解的同學(xué)-->傳送門(mén):iOS多線程詳細(xì)說(shuō)明(GCD篇-就是個(gè)玩兒)

NSOperation

NSOperation 是個(gè)抽象類,并不具備封裝操作的能力,必須使?它的子類:NSInvocationOperation(任務(wù))、NSBlockOperation(任務(wù))、NSOperationQueue(隊(duì)列)

1.NSInvocationOperation(任務(wù))

NSInvocationOperation 的作用是創(chuàng)建一個(gè)任務(wù),我們來(lái)看一下具體的代碼

- (void)viewDidLoad {
    [super viewDidLoad];
    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationRun) object:nil];
    [operation1 start];//?< 手動(dòng)開(kāi)始任務(wù)
}
- (void)operationRun
{
    NSLog(@"我是第一個(gè)queue%@",[NSThread currentThread]); //?< 主線程
}

這里我們值得注意的是,當(dāng)這個(gè)任務(wù)沒(méi)有添加到隊(duì)列中時(shí),默認(rèn)時(shí)在當(dāng)前線程中 同步 執(zhí)行的,并且任務(wù)創(chuàng)建以后,并沒(méi)有立即執(zhí)行需要我們手動(dòng)開(kāi)啟

2. NSBlockOperation(任務(wù))

NSBlockOperation的作用跟NSInvocationOperation一樣,只不過(guò)NSBlockOperation創(chuàng)建任務(wù)的形式是以block的形式來(lái)創(chuàng)建的。

- (void)viewDidLoad {
    [super viewDidLoad];
    NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"我是block任務(wù) %@",[NSThread currentThread]);
    }];
    [operation2 start];//?< 手動(dòng)開(kāi)始任務(wù)
}

當(dāng)然NSBlockOperation的任務(wù),也是默認(rèn)在當(dāng)前的線程下同步 執(zhí)行,也需要我們來(lái)手動(dòng)開(kāi)啟

3.NSOperationQueue(隊(duì)列)

NSOperationQueue(隊(duì)列) 和GCD中的并發(fā)隊(duì)列、串行隊(duì)列略有不同的是:NSOperationQueue一共有兩種隊(duì)列:主隊(duì)列、其他隊(duì)列。其中其他隊(duì)列同時(shí)包含了串行、并發(fā)功能。下邊是主隊(duì)列、其他隊(duì)列的基本創(chuàng)建方法和特點(diǎn)。

NSOperationQueue *mainQueue = [NSOperationQueue mainQueue]; //?< 主線程執(zhí)行
NSOperationQueue *otherQueue = [[NSOperationQueue alloc]init]; //?< 子線程執(zhí)行

3.2將任務(wù)添加到隊(duì)列


//僅以其它隊(duì)列舉例
NSOperationQueue *otherQueue = [[NSOperationQueue alloc]init]; //?< 子線程執(zhí)行

for (NSInteger i = 0; i < 0; i++) {
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"我是任務(wù)%ld %@",i,[NSThread currentThread]);
    }];
    //將任務(wù)添加到隊(duì)列中
    [otherQueue addOperation:op];
}

當(dāng)我們將任務(wù)添加到隊(duì)列中時(shí),不需要我們手動(dòng)去開(kāi)始任務(wù),任務(wù)會(huì)自動(dòng)開(kāi)始

3.2隊(duì)列的最大并發(fā)數(shù)

最大并發(fā)數(shù)就是指在這個(gè)隊(duì)列里面的任務(wù)(如果是并行的隊(duì)列),最多一次可以執(zhí)行任務(wù)的個(gè)數(shù)。
舉個(gè)例子用戶上傳100張照片,并且是異步的并發(fā)執(zhí)行,如果沒(méi)有設(shè)置最大并發(fā)數(shù)的話,那么這100個(gè)任務(wù)會(huì)一起執(zhí)行,且會(huì)影響性能,如果我們將最大并發(fā)數(shù)設(shè)置為10的話,則這個(gè)100個(gè)任務(wù)會(huì)被分成10組,每組10個(gè)任務(wù),10組任務(wù)間 一個(gè)一個(gè)執(zhí)行。

NSOperationQueue *otherQueue = [[NSOperationQueue alloc]init]; //?< 其它線程
//最大并發(fā)數(shù)
otherQueue.maxConcurrentOperationCount = 10;//?< 最大并發(fā)數(shù)
for (NSInteger i = 0; i < 100; i++) {
    NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"我是任務(wù)%ld %@",i,[NSThread currentThread]);
    [otherQueue addOperation:op];
}];

3.3隊(duì)列添加任務(wù)的其它方法(Block)

NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[queue addOperationWithBlock:^{
   //這里直接放任務(wù) 就可以了
    NSLog(@"我是block的任務(wù) %@",[NSThread currentThread]);
}];

4任務(wù)的依賴關(guān)系

相比GCD來(lái)說(shuō),NSOperation在設(shè)置依賴關(guān)系上要比GCD方便的多只需要很少的代碼就可以完成。假設(shè)需求: 2 , 3任務(wù)都完成后 再去完成op1;如果是GCD的話,我們可以用信號(hào)量、barrier來(lái)實(shí)現(xiàn)我們的效果,但是一般實(shí)現(xiàn)起來(lái)稍微有些麻煩,下面我們來(lái)看下NSOperation是如何來(lái)設(shè)置依賴關(guān)系的

// 任務(wù) 添加依賴關(guān)系
//創(chuàng)建兩個(gè)隊(duì)列
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
NSOperationQueue *otherQueue = [[NSOperationQueue alloc]init];

//創(chuàng)建3個(gè)任務(wù)
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"任務(wù)1  %@",[NSThread currentThread]);
}];

NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"任務(wù)2  %@",[NSThread currentThread]);
}];

NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
    NSLog(@"任務(wù)3  %@",[NSThread currentThread]);
}];
// 2  , 3任務(wù)都完成后 在完成op1
[op1 addDependency:op2];
[op1 addDependency:op3];

[otherQueue addOperation:op3];
[mainQueue addOperation:op2];
[otherQueue addOperation:op1];
//不受隊(duì)列的影響 隨意依賴

其中addDependency就是設(shè)置依賴關(guān)系的方法,只要一句就夠了,值得注意的是,所謂的依賴關(guān)系指的是任務(wù)之間的關(guān)系,而不是隊(duì)列的關(guān)系。

好今天就寫(xiě)到這,如果有哪里理解的不對(duì)的話,歡迎指出!嘻嘻嘻

最后編輯于
?著作權(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)容