本文僅做爲我的學習總結記錄使用!能力有限,不免會有疏漏和錯誤,還望指出。共同進步。html
工做學習IOS已經有半年了,一直都想抽出時間記錄一下本身的學習和工做經驗,但都寫到一半,就沒有而後了。關於併發編程,其實國外國內已經有各類牛人總結過很是棒的文章,但大多都是碎片化的文章。我就我的感覺而言,總結一下併發編程以及相關的一些知識。編程
關於併發編程,大部分的教程要麼是直接介紹GCD(Grand Central Dispatch
),要麼就是上一大堆的Operation Queues,還有介紹Threads來完成併發。後端
在移動和桌面操做系統中,蘋果提供了相同的併發編程API。 經常使用的分別是:pthread和NSThread,Grand Central Dispatch(GCD)以及NSOperationQueue
因爲高層API是基於底層API構建的,因此首先將從底層的API開始介紹,而後逐步介紹高層API,不過在具體編程中,選擇API的順序恰好相反:由於大多數狀況下,選擇高層的API不只能夠完成底層API能完成的任務,並且可以讓併發模型變得簡單。api
Threads
線程(thread)是組成進程的子單元,操做系統的調度器能夠對線程進行單獨的調度。實際上,全部的併發編程API都是構建於線程之上的——包括GCD和操做隊列(operation queues)。安全
通常在工做中,都不會使用pthread和NSThread,由於使用pthread或NSThread會引起一個問題:你建立了8個線程,而後在這些線程中調用了框架代碼,這些代碼也建立了一樣的線程(其實它並不知道你已經建立好線程了),這樣會很快產生成千上萬個線程,最終致使你的程序被終止執行——線程實際上並非免費的咖啡,每一個線程的建立都會消耗一些內容,以及相關的內核資源
基於隊列的併發編程API:GCD和operation queue。它們經過集中管理一個線程池(被沒一個任務協同使用),來解決上面遇到的問題閉包
Grand Central Dispatch
經過GCD,開發者不用再直接跟線程打交道了,只須要向隊列中添加block代碼便可,GCD在後端管理着一個線程池。GCD不只決定着哪一個線程(block)將被執行,它還根據可用的系統資源對線程池中的線程進行管理——這樣能夠不經過開發者來集中管理線程,緩解大量線程的建立,作到了讓開發者遠離線程的管理。
更多GCD的使用請參考:Low-Level Concurrency APIs併發
Operation Queues
操做隊列(operation queue)是基於GCD封裝的一個隊列模型。GCD提供了更加底層的控制,而操做隊列在GCD之上實現了一些方便的功能,這些功能對於開發者來講會更好、更安全。
關於Operation Queues比較好的文章:Common Background Practices框架
NSObject
若是你只想讓一些代碼在後臺執行,NSObject也提供了方法。這些方法的名字中都有「performSelector:」,最簡單的就是「performSelectorInBackground:withObject:」,它能在後臺執行一個方法。它經過建立一個線程來運行方法。定義這些方法必須遵循一下限制:函數
這些方法運行在各自的線程裏,所以你必須爲這些Cocoa對象建立一個自動釋放池,而主動釋放池是與主線程相關的。(arc,請無視)學習
這些方法不能有返回值,而且要麼沒有參數,要麼只能有一個參數。換句話說,你只能使用如下代碼格式中的一種。
記住這些限制,咱們實現的代碼應該以下所示:
-(void)myBackgroudMethod{ @autoreleasepool{ //todo } }
或
-(void)myOtherBackgroudMethod:(id)myObject{ @autoreleasepool{ // TODO } }
同時調用的時候,應該像這樣。
[self performSelectorInBackground:@selector(myBackgroudMethod) withObject:nil]; [self performSelectorInBackground:@ selector(myOtherBackgroudMethod:) withObject: myObject];
這樣就完成了。當方法執行結束後,OC運行時會特意清理並棄掉線程。須要注意,方法執行結束後並不會通知你:這是比較簡單的代碼
配合NSObject的
performSelectorOnMainThread
也能達到GCD的效果:
-(void)myOtherBackgroudMethod:(id)myObject{ @autoreleasepool{ // TODO [self performSelectorOnMainThread:@selector(updateUI:) withObject:obj waitUntilDone:YES]; } } -(void)updateUI:(NSObject *)obj{ // TODO }
我的認爲比較好的文章:
初識block:
Block劇終:Objective-C中的閉包性和匿名函數:
Gcd說到底其實就是方便操做線程的一個開源庫,並使用了block當作參數來傳遞這一特性。
Block其實就是OC的匿名函數,並具備閉包的特性,並且能夠很容易的獲取上下文的信息。和gcd有着本質的區別
以上都是我學習中的總結和註釋而已。篇幅很少,大多都是站在別人的肩膀上。主要是給本身回顧和完善知識體系用的。若是有不對的地方,歡迎指出。