多線程的意義:經過提升系統資源的利用率,充分發揮多核處理器的優點,併發(同時執行)執行任務讓系統運行的更快、更流暢多線程
NSThread(目前已經不經常使用)併發
在NSThread多線程中最經常使用的是NSObject封裝的多線程方法框架
-(void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg異步
這個方法能夠調用繼承自對象中實現的方法經過將其拋入到其餘後臺線程執行async
(SEL即爲須要調用的selector; arg爲向selector中傳遞的參數)函數
這個方法能夠修改程序的UI可是強烈不建議使用該方法直接修改界面.spa
若是須要在該方法中修改UI能夠調用控件的線程
-(void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;設計
方法來進行修改orm
performSelectorOnMainThread方法也是在nsobject類中封裝的多線程方法,該方法的做用是調用對象中的方法在主線程中執行
固然也可使用自定義線程的方式來實現多線程:
+(void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
NSThread的工廠方法,快速返回一個NSThread對象,該方法生成的線程會直接啓動
-(id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
NSthread的構造函數生成一個NSThread對象,該方法生成的線程對象須要手動調用start方法才能啓動
須要注意的是在NSThread方式實現多線程的時候須要給每個線程定義一個autoreleasepool,不然會出現內存泄露
NSOperation/NSOperationQueue
這是一種面向對象的多線程技術, 因其對另外兩種進行了封裝,因此相比較其餘兩種有更加全面的功能;
通常步驟:
建立一個NSOperation
建立或者獲取一個NSOperationQueue
將操做添加到隊列中
NSOperation分爲兩個子類
NSInvocationOperation
- (id)initWithTarget:(id)target selector:(SEL)sel object:(id)arg;
這個方法有些相似於NSThread 主要就是須要把拋出的操做封裝到target的一個對象方法中,能夠傳一個參數;
NSBlockOperation(我的感受最好用的)
+ (id)blockOperationWithBlock:(void (^)(void))block;
工廠方法快速生成一個blockOperation,該方法的好處就是不須要再定義一個方法,而block做爲一個參數傳遞進去能夠極大地加強代碼的擴展性,下降代碼間的耦合度,方便後期維護.
建立好了nsoperation以後就須要將它添加到指定的隊列中去了當操做被加入到隊列中的時候就馬上處於激活狀態開始執行了;
NSOperation的start方法能夠將該操做加入到當前的操做隊列中.
另外,值得一提的是NSOperation方式實現多線程相比較其餘兩種最大的好處就是能夠限制併發的線程數
-(void) maxConcurrentOperationCount;
這個方法是NSOperationQueue的對象方法,用來限制當前操做隊列同時併發的線程數
在一個程序中,每多開一個線程就會多佔用一些系統資源,在iOS環境下主線程的棧內存是1M以後每開一個子線程會佔用系統512k的棧內存,因此在實際的開發中控制併發的線程數是很是重要的.
NSOperation對象之間的依賴關係:
在多線程開發中,若是幾個操做之間有依賴關係是很是使人頭疼的一件事,可是NSOperation能夠很簡單的處理不一樣線程之間的操做依賴關係例如,有三個操做分別爲op1, op2, op3.三個操做須要按照順序執行代碼以下:
[op2 addDependency:op1];
[op3 addDependency:op2];
這種依賴關係並不受所在的操做隊列限制也就是說,即便op1,op2處於子線程並且是很是耗時的操做,op3處於主線程.op3也會等到op2執行完畢後纔會執行,這樣在實際的開發中是很是方便的,由於在開發中操做隊列中的操做並非按照添加順序來執行的,而添加依賴就保證了它們可以按照規定的順序執行
Gcd
GCD 是一套基於C語言的框架,發佈於iOS4.0,其設計的初衷就是爲了更好的發揮多核處理器的優點,底層是經過線程實現的,GCD是蘋果官方推薦使用的多線程技術;
首先介紹一下GCD的三種隊列:
全局隊列:全部添加到該隊列的任務都是併發執行的;
串行隊列:全部添加到串行隊列的任務都是順序執行的;
主隊列:添加到主隊列中的任務都是在主線程執行的;
各隊列的獲取方法:
全局隊列:
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)
參數說明:第一個參數是該隊列的優先級,建議使用默認,若無特殊要求最好不要隨意設置優先級
第二個參數是預留參數,須要填0
串行隊列:
dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);
參數說明:這是一個建立隊列的方法,第一個參數是隊列名這個能夠本身隨意,第二個參數有兩個值DISPATCH_QUEUE_SERIAL表示建立一個串行隊列
DISPATCH_QUEUE_CONCURRENT表示建立一個並行隊列(感受意義不大由於已經有了全局隊列)
主隊列: dispatch_queue_t queue =dispatch_get_main_queue();
以上就是三種隊列的獲取方法
下面開始介紹GCD中任務執行方法
GCD任務執行分爲同步方法和異步方法,其實實際是同步仍是異步須要方法名和執行隊列共同來決定的,這就須要讀者本身多去練習才能徹底理解
首先是異步方法
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
參數:第一個參數爲執行隊列第二個參數是任務的代碼塊
同步方法:
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
參數與異步方法傳入參數同樣
這裏因爲有兩種執行方法,四種隊列組合方式實在是太多,我也就不一一列舉了,若是想要了解GCD其實最直接的方法就是,分別給兩種方法傳入不一樣的隊列,而後按照各類順序調用,只有多練習才能徹底掌握;
其實GCD在實際使用中是很是簡單的
只須要兩步而已:
第一步獲取一個執行隊列,第二步將操做同步或者異步的加入到執行隊列中去
注:示例代碼我在找一個比較穩定的網盤,因此會稍後上傳