iOS基礎 - 多線程線程

1、多線程的應用

l 充分發揮多核處理器的優點,併發(同時執行)執行任務讓系統運行的更快、更流暢程序員

2、進程與線程概念

l 一個運行的程序就是一個進程或者叫作一個任務編程

l 一個進程至少包含一個線程,線程是程序的執行流安全

l iOS程序啓動時,在建立一個進程的同時, 會開始運行一個線程,該線程被稱爲主線程多線程

l 主線程是其餘線程最終的父線程,全部界面的顯示操做必須在主線程進行!!!併發

l 後臺線程沒法更新UI界面和響應用戶點擊事件框架

l 系統中的每個進程都有本身獨立的虛擬內存空間,而同一個進程中的多個線程則共用進程的內存空間異步

l 每建立一個新的線程,都會消耗必定內存和CPU時間async

l 當多個線程對同一個資源出現爭奪的時候須要注意線程安全問題函數

3、多線程的優點與難點

l 優點性能

  • 充分發揮多核處理器優點,將不一樣線程任務分配給不一樣的處理器,真正進入「並行運算」狀態
  • 將耗時、輪詢或者併發需求高等任務分配到其餘線程執行,並由主線程負責統一更新界面會使得應用程序更加流暢,用戶體驗更好
  • 當硬件處理器的數量增長,程序會運行更快,而無需作任何調整

l 難點

  • 共享資源的「爭奪」
  • 多線程是爲了同步完成多項任務,不是爲了提升運行效率,而是爲了經過提升資源使用效率來提升系統的總體性能

4、多線程使用注意事項

l 線程使用不是無節制的

  • iOS中的主線程的堆棧大小是1M
  • 從第二個線程開始都是512KB
  • 這些數值不能經過編譯器開關或線程API函數更改

l 只有主線程有直接修改UI的能力

5、iOS的三種多線程技術

l NSThread 每一個NSThread對象對應一個線程,量級較輕(真正的多線程)

l 如下兩點是蘋果專門開發的「併發」技術,使得程序員能夠再也不去關心線程的具體使用問題

  • NSOperation/NSOperationQueue 面向對象的線程技術
  • GCD —— Grand Central Dispatch(派發) 是基於C語言的框架,能夠充分利用多核,是蘋果推薦使用的多線程技術

以上這三種編程方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單,也是Apple最推薦使用的。可是就目前而言,iOS的開發者,須要瞭解三種多線程技術的基本使用過程。由於不少框架技術分別使用了不一樣多線程技術。

6、三種多線程技術的對比

l NSThread:

  • 優勢:NSThread 比其餘兩個輕量級,使用簡單
  • 缺點:須要本身管理線程的生命週期、線程同步、加鎖、睡眠以及喚醒等。線程同步對數據的加鎖會有必定的系統開銷

l NSOperation

  • 不須要關心線程管理,數據同步的事情,能夠把精力放在本身須要執行的操做上
  • NSOperation是面向對象的

l GCD

  • Grand Central Dispatch是由蘋果開發的一個多核編程的解決方案。iOS4.0+才能使用,是替代NSThread, NSOperation的高效和強大的技術
  • GCD是基於C語言的

7、NSObject的多線程方法後臺線程

- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg

一般,因爲線程管理相對比較繁瑣,而不少耗時的任務又沒法知道其準確的完成時間,所以可使用performSelectorInBackground方法直接新建一個後臺線程,並將選擇器指定的任務在後臺線程執行,而無需關心具體的NSThread對象

  • performSelectorInBackground方法自己是在主線程中執行的,而選擇器指定的方法是在後臺線程中進行的
  • 使用performSelectorInBackground方法調用的任務能夠更新UI界面
  • 在大型交互式遊戲中,一般使用此方法在後臺線程播放音效

8、@autoreleasepool

l 內存管理對於多線程很是重要

l Objective-C能夠憑藉@autoreleasepool使用內存資源,並須要時回收資源

l 每一個線程都須要有@autoreleasepool,不然可能會出現內存泄漏

9、NSObject的多線程方法主線程

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

若是要更新UI界面,能夠在後臺線程中調用performSelectorOnMainThread方法

儘管使用performSelectorInBackground方法調用的任務能夠更新UI界面,可是在實際開發中,涉及到UI界面的更新操做,仍是要使用performSelectorOnMainThread方法,以免沒必要要的麻煩

10、NSThread

l 建立線程方法:

+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;

- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

l 參數說明:

selector:線程執行的方法,只能有一個參數,不能有返回值

targetselector消息發送的對象

argument:傳輸給target的惟一參數,也能夠是nil

11、NSOperation & NSOperationQueue

l NSOperation的兩個子類

NSInvocationOperation

NSBlockOperation

l 工做原理:

NSOperation封裝要執行的操做

將建立好的NSOperation對象放NSOperationQueue

啓動OperationQueue開始新的線程執行隊列中的操做

l 注意事項:

使用多線程時一般須要控制線程的併發數,由於線程會消耗系統資源,同時運行的線程過多,系統會變慢

使用如下方法能夠控制併發的線程數量:

(void)setMaxConcurrentOperationCount:(NSInteger)cnt;

12、GCD

l GCD是基於C語言的框架

l 工做原理:

讓程序平行排隊的特定任務,根據可用的處理資源,安排它們在任何可用的處理器上執行任務

要執行的任務能夠是一個函數或者一個block

底層是經過線程實現的,不過程序員能夠沒必要關注實現的細節

GCD中的FIFO隊列稱爲dispatch queue,能夠保證先進來的任務先獲得執行

dispatch_notify 能夠實現監聽一組任務是否完成,完成後獲得通知

l GCD隊列:

全局隊列:全部添加到主隊列中的任務都是併發執行的

串行隊列:全部添加到串行隊列中的任務都是順序執行的

主隊列:全部添加到主隊列中的任務都是在主線程中執行的

十3、獲取隊列的方法

l 全局隊列(可能會開啓多條線程)

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

l 串行隊列(只可能會開啓一條線程)

dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

l 主隊列

dispatch_get_main_queue();

十4、GCD任務的執行方式同步&異步

l 異步操做

dispatch_async 在其餘線程執行任務,會開啓新的線程

異步方法沒法肯定任務的執行順序

l 同步操做

dispatch_sync 在當前在當前線程執行任務,不開啓新的線程

同步操做與隊列無關

同步方法會依次執行,可以決定任務的執行順序

更新界面UI時,最好使用同步方法

十5、GCD的優勢

l 充分利用多核

l 全部的多線程代碼集中在一塊兒,便於維護

l GCD中無需使用@autoreleasepool

l 若是要順序執行,可使用dispatch_sync同步方法

l dispatch_async沒法肯定任務的執行順序 

十6、單例模型

l 目的:

保證在內存中永遠只有類的單個實例

l 創建方法:

聲明一個靜態成員變量,記錄惟一實例

重寫allocWithZone方法

allocWithZone方法是對象分配內存空間時,最終會調用的方法,重寫該方法,保證只會分配一個內存空間

創建sharedXXX類方法,便於其餘類訪問

互斥鎖的目的,一次只讓一個線程訪問資源,從而達到資源的線程安全。

相關文章
相關標籤/搜索