IOS 多線程 有三種主要方法(1)NSThread(2)NSOperation(3)GCD下面簡單介紹這三個方法
1.NSThread 調用方法如下:
如函數需要輸入參數,可從object傳進去。 (1) [NSThread detachNewThreadSelector:@selector(threadInMainMethod:) toTarget:self withObject:nil]; (2) NSThread* myThread = [[NSThread alloc] initWithTarget:self selector:@selector(threadInMainMethod:) object:nil]; [myThread start]; (3) [obj performSelectorInBackground:@selector(threadMe) withObject:nil];提個問題:如果某個ViewController裡運行了一個Thread,Thread還沒結束的時候,這個ViewController被Release了,結果會如何?
經過的的測試,Thread不結束,ViewController一直保留,不會執行dealloc方法。
2.NSOperation
NSoperation也是多線程的一種,NSopertaion有2種形式 (1) 並發執行 並發執行你需要重載如下4個方法 //執行任務主函數,線程啟動並執行入口函數 - (void)start //是否允許並發,返回YES,允許並發,返回NO不允許。預設返回NO -(BOOL)isConcurrent - (BOOL)isExecuting //是否已經完成,這個必須要重載,不然放在放在NSOperationQueue裡的NSOpertaion不能正常釋放。 - (BOOL)isFinished 比如TestNSOperation:NSoperaion 重載上述的4個方法, 聲明一個NSOperationQueue, NSOperationQueue *queue = [[[NSOperationQueue alloc ] init] autorelease]; [queue addOperation:testNSoperation]; 它會自動調用TestNSOperation裡的 start函數,如果需要多個NSOperation,你需要設定queue的一些屬性,如果多個NSOperation之間又依賴關係,也可以設定,具體可以參考API 文檔。
(2)非並發執行 -(void)main 只需要重載這個main方法就可以了。 3.GCD
GCD很強大,我的使用經驗很少。但是scorpiozj 總結的比較全面(http://www.cnblogs.com/scorpiozj/archive/2011/07/25/2116459.html)
同時,這篇文章也介紹的比較詳細 http://www.cnblogs.com/vinceoniphone/archive/2011/04/07/2007968.html
官方教程
GCD是和block緊密相連的,所以最好先瞭解下block(可以查看這裡).GCD是C level的函數,這意味著它也提供了C的函數指標作為參數,方便了C程式員.
下面首先來看GCD的使用:
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
async表明非同步運行,block代表的是你要做的事情,queue則是你把任務交給誰來處理了.(除了async,還有sync,delay,本文以async為例).
之所以程式中會用到多線程是因為程式往往會需要讀取資料,然後更新UI.為了良好的使用者體驗,讀取資料的操作會傾向於在後台運行,這樣以避免阻塞主線程.GCD裡就有三種queue來處理.
1. Main queue:
顧名思義,運行在主線程,由dispatch_get_main_queue獲得.和ui相關的就要使用Main Queue.
2.Serial quque(private dispatch queue)
每次運行一個任務,可以添加多個,執行次序FIFO(隊列,先進先出first input first out). 通常是指程式員產生的,比如:
dispatch_queue_t myCustomQueue = dispatch_queue_create("example.MyCustomQueue", NULL);
dispatch_async(myCustomQueue, ^{
for (int abc=0;abc<100;abc++)
{
printf("1.Do some work here.\n");
}
});
dispatch_async(myCustomQueue, ^{
for (int abc=0;abc<100;abc++)
{
printf("2.Do some work here.\n");
}
});
dispatch_queue_t myCustomQueue2 = dispatch_queue_create("example.MyCustomQueue2", NULL);
dispatch_async(myCustomQueue2, ^{
for (int abc=0;abc<100;abc++)
{
printf("1. myCustomQueue2 Do some work here.\n");
}
});
dispatch_async(myCustomQueue2, ^{
for (int abc=0;abc<100;abc++)
{
printf("2. myCustomQueue2 Do some work here.\n");
}
});
列印的結果必定會是 :然而,因為myCustomQueue 和 myCustomQueue2 是在兩個隊列中,所以在隊列myCustomQueue中:
“1.Do some work here.” 在 “2.Do some work here.” 之前,而在myCustomQueue2隊列中:“1. myCustomQueue2
Do some work here.”在“2. myCustomQueue2 Do some work here.”之前。而在myCustomQueue和myCustomQueue2
之中的任務是沒有先後的。及不是並發的。
3. Concurrent queue(global dispatch queue):
可以同時運行多個任務,每個任務的啟動時間是按照加入queue的順序,結束的順序依賴各自的任務.使用dispatch_get_global_queue獲得.
所以我們可以大致瞭解使用GCD的架構:
dispatch_queue_t newThread = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(newThread,^{[selfdownloadImage:ImageURL];
});
小節:NSThread的方式或許能做更快的切換,因為ARMv6或更高版本的處理器都提供了非常強大的線程切換機制。但是NSThread不會
採取多核的指派,因為這個系統介面首先要保證的是使用者線程的可靠性。 而Grand Central Dispatch顯式地利用指派隊列來做多核
指派調度,因此如果是在多核處理器上的話用G_C_D更快。如果你的處理器是單核心的話,那麼可以使用切換更快的NSThread。
Where do I find GCD?
1. GCD is part of libSystem.dylib
2. #include <dispatch/dispatch.h>