iOS有三種多線程程式設計的技術,分别是:
(一) NSThread
(二)Cocoa NSOperation
(三)GCD(全稱:Grand Central Dispatch)
這三種程式設計方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單,也是Apple最推薦使用的。
三種方式介紹:
1)NSThread
在處理機制上,需要開發者負責手動管理Thread的生命周期,包括子線程與主線程之間的同步等。線程共享同一應用程式的部分記憶體空間,它們擁有對資料相同的通路權限。你得協調多個線程對同一資料的通路,一般做法是在通路之前加鎖,這會導緻一定的性能開銷。
2)NSOperation
可以認為NSOperationQueue就是一個線程管理器,通過addOperation方法,我們可以一次性把多個線程添加到隊列中。同時,NSOperationQueue允許通過setMaxConcurrentOperationCount方法設定隊列并行執行的線程數量。
3)GCD
GCD是Apple開發的一個多核程式設計的解決方法。該方法在Mac OS X 10.6雪豹中首次推出,并随後被引入到了iOS4.0中。GCD是一個替代諸如NSThread,NSOperationQueue,NSInvocationOperation等技術的很高效和強大的技術。
三種方式的優缺點介紹:
1)NSThread:
優點:NSThread 比其他兩個輕量級
缺點:需要自己管理線程的生命周期,線程同步。線程同步對資料的枷鎖會有一定的系統開銷。
2)Cocoa NSOperation
優點:不需要關心線程管理,資料同步的事情,可以把精力放在自己需要執行的操作上。
Cocoa operation相關的類是 NSOperation, NSOperationQueue.
NSOperation是個抽象類,使用它必須使用它的子類,可以實作它或者使用它定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation.
NSOperationQueue是線程隊列,裡面存放需要執行的線程。 建立NSOperation子類的對象,把對象添加到NSOperationQueue隊列裡執行。
3)GCD
優點:GCD比之thread更簡單易用。并且處理效率很高。GCD自動根據系統負載來增減線程數量,這就減少了上下文切換以及增加了計算效率。
三種方法的方法介紹:
1)NSThread:
建立方式主要有兩種:
[NSThread detachNewThreadSelector:@selector(myThreadMainMethod:) toTarget:self withObject:nil];
和
NSThread* myThread = [[NSThread alloc] initWithTarget:self
selector:@selector(myThreadMainMethod:)
object:nil];
[myThread start]; //啟動線程
這兩種方式的差別是:前一種一調用就會立即建立一個線程來做事情;而後一種雖然你 alloc 了也 init了,但是要直到我們手動調用 start 啟動線程時才會真正去建立線程。這種延遲實作思想在很多跟資源相關的地方都有用到。後一種方式我們還可以在啟動線程之前,對線程進行配置,比如設定 stack 大小,線程優先級。
此外還有一種間接的方式:利用NSObject的方法
performSelectorInBackground:withObject: 來建立一個線程:
[myObj performSelectorInBackground:@selector(myThreadMainMethod) withObject:nil]; //在背景運作某一個方法
其效果與 NSThread 的 detachNewThreadSelector:toTarget:withObject: 是一樣的。
2)NSOperationQueue:
1> 使用步驟:
1) 執行個體化操作
_queue = [[NSOperationQueue alloc] init];
a) NSInvocationOperation
NSInvocationQperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(opAction) object:nil];
// 如果使用start,會在目前線程啟動操作
[op1 start];
//一旦将操作添加到操作隊列,操作就會啟動
[_queue addOperation:op1];
b) NSBlockOperation
#pragma mark -模仿下載下傳網絡圖像
- (IBAction)operationDemo3:(id)sender
{
//1.下載下傳
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下載下傳%@",[NSThread currendThread]);
}];
// 2.濾鏡
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"下載下傳%@",[NSThread currendThread]);
}];
//3.顯示
NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"更新UI%@",[NSThread currendThread]);
}];
//添加操作之間的依賴關系,所謂“依賴”關系,就是等待前一個任務完成後,後一個任務才能啟動
//依賴關系可以跨線程隊列實作
//提示:在指定依賴關系時,注意不要循環依賴,否則不工作。
[op2 addDepandency:op1];
[op3 addDependency:op2];
[_queue addOperation:op1];
[_queue addOperation:op2];
[[NSOperationQueue mainQueue] addOperation:op3];
}
2) 将操作添加到隊列NSOperationQueue即可啟動多線程執行
[_queue addOperation:op1];
[_queue addOperation:op2];
2> 更新UI使用主線程隊列
//兩方式
[[NSOperationQueue mainQueue] addOperation:^{
[[NSOperationQueue mainQueue] addOperation:op3];
}];
3> 操作隊列的setMaxConcurrentOperationCount
可以設定同時并發的線程數量!
[_queue setMacConcurrentOperationCount:2];
提示:此功能僅有NSOperation有!
4> 使用addDependency可以設定任務的執行先後順序,同時可以跨操作隊列指定依賴關系
[op2 addDependency:op1];
[op3 addDependency:op2];
[op1 addDepandency:op3];
提示:在指定依賴關系時,注意不要循環依賴,否則不工作。