1. 程式人生 > >IOS多執行緒之NSThread

IOS多執行緒之NSThread

A一條線,B一條線,平行遙相望,不知何時相交。

C一個執行緒,D一個執行緒,齊頭並進,最好不相聚。

21(圖片選自百度)

做過開發的都知道,為了使用者體驗好,耗時長的case我們都放到子執行緒去做,譬如:下載,資料訪問,網路訪問等。

在IOS中,多執行緒有三種技術,NSThread,NSOperation,GCD,其中NSThread和大家平時各語言中使用的Thread類似。

彙總:

  1. NSThread:比其他兩個要輕量級,建立一個執行緒十分方便,但需要我們自己維護生命週期和執行緒同步,所以不建議用它來實現多執行緒。建議用[NSThread currentThread]來跟蹤任務所線上程十分方便,且適用於這三種技術。
  2. NSOperation/NSOperationQueue:由GCD實現的一套Objective-C的API,面向物件的多執行緒技術,但它提供了一些在GCD中不容易實現的特性,如:限制最大併發數量,設定各操作間的依賴關係。操作佇列比GCD效能要略低,但可以忽略不計,在併發程式設計中,推薦使用NSOperation/NSOperationQueue
  3. GCD:是基於C語言的底層API,我們不用去關心它的內部實現。它使用Block定義任務,使用起來十分靈活,提供了更多的控制能力以及NSOperationQueue中所不能使用的底層函式。抽象度最高,使用最簡單,蘋果最推薦使用的多執行緒程式設計技術(為多核的並行運算提出的解決方案)。

這一篇,我們先介紹NSThread的使用:

NSThread的方法介紹:

  • 獲取當前執行的執行緒:

[NSThread currentThread];

  • 自動建立一個新的執行緒執行target物件的func方法,引數通過argument物件傳入(只能傳遞一個引數,如果有多個請使用物件封裝哦):

[NSThread detachNewThreadSelector:@selector(func) toTarget:target withObject:argument];

  • 判斷是否為多執行緒:

[NSThread isMultiThreaded];

  • 阻塞當前執行緒到某個時間,date為這個時間點NSDate型別

[NSThread sleepUntilDate:date];

  • 阻塞當前執行緒多長時間,time單位為秒(NSTimeInterval)

[NSThread sleepForTimeInterval:time];

  • 強制終止執行緒:

寫線上程內部,退出當前執行緒:

[NSThread exit];
  • 排程優先順序:

排程優先順序的取值範圍是0.0 ~ 1.0,預設0.5,值越大,優先順序越高

自己開發時,不要修改優先順序,否則一旦出現“優先順序反轉”會非常麻煩

thread. threadPriority = 1;

  • 判斷當前執行緒是不是主執行緒:

[NSThread isMainThread];

  • 判斷thread是不是主執行緒:

thread.isMainThread;//readonly

  • 獲取主執行緒:

[NSThread mainThread];

  • 執行緒初期化:

[[NSThread alloc] init];

  • 初期化執行緒,啟動後會呼叫target的func方法,引數通過argument物件傳入(只能傳遞一個引數,如果有多個請使用物件封裝):

與detachNewThreadSelector不同的是,需要自己呼叫start方法啟動。

NSThread *thread = [[NSThread alloc] initWithTarget:target selector:@selector(func) object:argument];

[thread start];

  • 判斷執行緒是否在執行:

thread.isExecuting;//(readonly)

  • 判斷執行緒是否執行完畢:

isFinished;//(readonly)

  • 判斷執行緒是否已被取消:

isCancelled;//(readonly)

  • 開始執行執行緒:

[thread start];

  • 取消執行該執行緒:

[thread cancel];

另外還有一些關於執行緒的方法,屬於NSObject:

  • 主執行緒執行某操作:(在子執行緒完成後更新UI時常用)

注:子執行緒任務完成後,需要更新頁面,子執行緒本身是不能操作UI的,所以需要排程到主執行緒中執行更新UI的方法:

aSelector:在主執行緒要執行的方法;

arg:方法需要的引數

wait:YES指定,同步阻塞,當前執行緒被阻塞,直到主執行緒將我們制定的程式碼塊執行完才進行當前執行緒後面程式碼;

NO指定,非同步非阻塞,當前執行緒和主執行緒非同步執行。

[self performSelectorOnMainThread:@selector(aSelector) withObject:arg waitUntilDone:wait];

  • 子執行緒執行某操作:

引數與performSelectorOnMainThread:withObject:waitUntilDone:方法一致,除了多了個onThread:,其引數是你要執行aSelector方法的自定義執行緒。

NSThread *thr = [[NSThread alloc] init];

[self performSelector:@selector(aSelector) onThread:thr withObject:arg waitUntilDone:wait];

  • 後臺執行某操作:

[self performSelectorInBackground:@selector(aSelector) withObject:arg];

以上方法的arg引數,當aSelector方法沒有引數的時候,arg設為nil即可。

NSThread的detachNewThreadSelector:toTarget:withObject:方法和NSObject的perform開頭的執行緒方法都是執行完該行程式碼後立即執行指定執行緒操作。NSThread的init開頭的方法建立的執行緒需要自己手動呼叫start方法後才執行,當然,並不是說後者不好哦,後者可以設定好執行緒的屬性後再執行。各有各的好處,根據自己需要即可。