l 充分發揮多核處理器的優點,併發(同時執行)執行任務讓系統運行的更快、更流暢程序員
l 一個運行的程序就是一個進程或者叫作一個任務編程
l 一個進程至少包含一個線程,線程是程序的執行流安全
l iOS程序啓動時,在建立一個進程的同時, 會開始運行一個線程,該線程被稱爲主線程多線程
l 主線程是其餘線程最終的父線程,全部界面的顯示操做必須在主線程進行!!!併發
l 後臺線程沒法更新UI界面和響應用戶點擊事件框架
l 系統中的每個進程都有本身獨立的虛擬內存空間,而同一個進程中的多個線程則共用進程的內存空間異步
l 每建立一個新的線程,都會消耗必定內存和CPU時間async
l 當多個線程對同一個資源出現爭奪的時候須要注意線程安全問題函數
l 優點性能
l 難點
l 線程使用不是無節制的
l 只有主線程有直接修改UI的能力
l NSThread 每一個NSThread對象對應一個線程,量級較輕(真正的多線程)
l 如下兩點是蘋果專門開發的「併發」技術,使得程序員能夠再也不去關心線程的具體使用問題
以上這三種編程方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單,也是Apple最推薦使用的。可是就目前而言,iOS的開發者,須要瞭解三種多線程技術的基本使用過程。由於不少框架技術分別使用了不一樣多線程技術。
l NSThread:
l NSOperation:
l GCD:
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
一般,因爲線程管理相對比較繁瑣,而不少耗時的任務又沒法知道其準確的完成時間,所以可使用performSelectorInBackground方法直接新建一個後臺線程,並將選擇器指定的任務在後臺線程執行,而無需關心具體的NSThread對象
l 內存管理對於多線程很是重要
l Objective-C能夠憑藉@autoreleasepool使用內存資源,並須要時回收資源
l 每一個線程都須要有@autoreleasepool,不然可能會出現內存泄漏
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
若是要更新UI界面,能夠在後臺線程中調用performSelectorOnMainThread方法
儘管使用performSelectorInBackground方法調用的任務能夠更新UI界面,可是在實際開發中,涉及到UI界面的更新操做,仍是要使用performSelectorOnMainThread方法,以免沒必要要的麻煩
l 建立線程方法:
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
l 參數說明:
selector:線程執行的方法,只能有一個參數,不能有返回值
target:selector消息發送的對象
argument:傳輸給target的惟一參數,也能夠是nil
l NSOperation的兩個子類
NSInvocationOperation
NSBlockOperation
l 工做原理:
用NSOperation封裝要執行的操做
將建立好的NSOperation對象放NSOperationQueue中
啓動OperationQueue開始新的線程執行隊列中的操做
l 注意事項:
使用多線程時一般須要控制線程的併發數,由於線程會消耗系統資源,同時運行的線程過多,系統會變慢
使用如下方法能夠控制併發的線程數量:
(void)setMaxConcurrentOperationCount:(NSInteger)cnt;
l GCD是基於C語言的框架
l 工做原理:
讓程序平行排隊的特定任務,根據可用的處理資源,安排它們在任何可用的處理器上執行任務
要執行的任務能夠是一個函數或者一個block
底層是經過線程實現的,不過程序員能夠沒必要關注實現的細節
GCD中的FIFO隊列稱爲dispatch queue,能夠保證先進來的任務先獲得執行
dispatch_notify 能夠實現監聽一組任務是否完成,完成後獲得通知
l GCD隊列:
全局隊列:全部添加到主隊列中的任務都是併發執行的
串行隊列:全部添加到串行隊列中的任務都是順序執行的
主隊列:全部添加到主隊列中的任務都是在主線程中執行的
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();
l 異步操做
dispatch_async 在其餘線程執行任務,會開啓新的線程
異步方法沒法肯定任務的執行順序
l 同步操做
dispatch_sync 在當前在當前線程執行任務,不開啓新的線程
同步操做與隊列無關
同步方法會依次執行,可以決定任務的執行順序
更新界面UI時,最好使用同步方法
l 充分利用多核
l 全部的多線程代碼集中在一塊兒,便於維護
l GCD中無需使用@autoreleasepool
l 若是要順序執行,可使用dispatch_sync同步方法
l dispatch_async沒法肯定任務的執行順序
l 目的:
保證在內存中永遠只有類的單個實例
l 創建方法:
聲明一個靜態成員變量,記錄惟一實例
重寫allocWithZone方法
allocWithZone方法是對象分配內存空間時,最終會調用的方法,重寫該方法,保證只會分配一個內存空間
創建sharedXXX類方法,便於其餘類訪問
互斥鎖的目的,一次只讓一個線程訪問資源,從而達到資源的線程安全。