談iOS多線程(NSThread、NSOperation、GCD)編程

一.基本概念

計算機操作系統(tǒng)都有的基本概念,以下概念簡單方式來描述。

進程: 一個具有一定獨立功能的程序關于某個數(shù)據(jù)集合的一次運行活動??梢岳斫獬梢粋€運行中的應用程序。

線程: 程序執(zhí)行流的最小單元,線程是進程中的一個實體。

同步: 只能在當前線程按先后順序依次執(zhí)行,不開啟新線程。

異步: 可以在當前線程開啟多個新線程執(zhí)行,可不按順序執(zhí)行。

隊列: 裝載線程任務的隊形結(jié)構(gòu)。

并發(fā): 線程執(zhí)行可以同時一起進行執(zhí)行。

串行: 線程執(zhí)行只能依次逐一先后有序的執(zhí)行。

注意:

一個進程可有多個線程。

一個進程可有多個隊列。

隊列可分并發(fā)隊列和串行隊列。

二.iOS多線程對比

1. NSThread

每個NSThread對象對應一個線程,真正最原始的線程。

1)優(yōu)點:NSThread 輕量級最低,相對簡單。

2)缺點:手動管理所有的線程活動,如生命周期、線程同步、睡眠等。

2. NSOperation

自帶線程管理的抽象類。

1)優(yōu)點:自帶線程周期管理,操作上可更注重自己邏輯。

2)缺點:面向?qū)ο蟮某橄箢?,只能實現(xiàn)它或者使用它定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation。

3. GCD

Grand Central Dispatch (GCD)是Apple開發(fā)的一個多核編程的解決方法。

1)優(yōu)點:最高效,避開并發(fā)陷阱。

2)缺點:基于C實現(xiàn)。

5. 選擇小結(jié)

1)簡單而安全的選擇NSOperation實現(xiàn)多線程即可。

2)處理大量并發(fā)數(shù)據(jù),又追求性能效率的選擇GCD。

3)NSThread本人選擇基本上是在做些小測試上使用,當然也可以基于此造個輪子。

三.場景選擇

圖片異步加載。這種常見的場景是最常見也是必不可少的。異步加載圖片有分成兩種來說明一下。

第一種,在UI主線程開啟新線程按順序加載圖片,加載完成刷新UI。

第二種,依然是在主線程開啟新線程,順序不定地加載圖片,加載完成個字刷新UI。

創(chuàng)作工具上的異步。 這個跟上邊任務調(diào)度道理,只是為了豐富描述,有助于“舉一反三”效果。如下描述的是app創(chuàng)作小說。

場景一,app本地創(chuàng)作10個章節(jié)內(nèi)容未成同步服務器,同時發(fā)表這10個章節(jié)產(chǎn)生的一系列動作,其中上傳內(nèi)容,獲取分配章節(jié)Id,如何后臺沒有做處理最好方式做異步按順序執(zhí)行。

場景二,app本地創(chuàng)作列表中有3本小說為發(fā)表,同時發(fā)表創(chuàng)作列表中的3本小說,自然考慮并行隊列執(zhí)行發(fā)表。

四.使用方法

第三標題場景選擇內(nèi)容實現(xiàn)先留下一個懸念。具體實現(xiàn)還是先熟知一下各自的API先。

1. NSThread

1.1)三種實現(xiàn)開啟線程方式:

①.動態(tài)實例化

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadImageSource:) object:imgUrl];

thread.threadPriority = 1;// 設置線程的優(yōu)先級(0.0 - 1.0,1.0最高級)

[thread start];

②.靜態(tài)實例化

[NSThread detachNewThreadSelector:@selector(loadImageSource:) toTarget:self withObject:imgUrl];

③.隱式實例化

[self performSelectorInBackground:@selector(loadImageSource:) withObject:imgUrl];

有了以上的知識點,可以試探了一下編寫場景選擇中的“圖片加載”的基本功能了。

1.2)使用這三種方式編寫代碼

//動態(tài)創(chuàng)建線程

-(void)dynamicCreateThread{

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadImageSource:) object:imgUrl];

thread.threadPriority = 1;// 設置線程的優(yōu)先級(0.0 - 1.0,1.0最高級)

[thread start];

}

//靜態(tài)創(chuàng)建線程

-(void)staticCreateThread{

[NSThread detachNewThreadSelector:@selector(loadImageSource:) toTarget:self withObject:imgUrl];

}

//隱式創(chuàng)建線程

-(void)implicitCreateThread{

[self performSelectorInBackground:@selector(loadImageSource:) withObject:imgUrl];

}

-(void)loadImageSource:(NSString *)url{

NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:url]];

UIImage *image = [UIImage imageWithData:imgData];

if (imgData!=nil) {

[self performSelectorOnMainThread:@selector(refreshImageView:) withObject:image waitUntilDone:YES];

}else{

NSLog(@"there no image data");

}

}

-(void)refreshImageView:(UIImage *)image{

[self.imageView setImage:image];

}

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

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

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