你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> IOS開發之多線程

IOS開發之多線程

編輯:IOS技巧綜合
[摘要]本文是對IOS開發之多線程 -- GCD的方方面面的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

前言:這篇GCD的博文是本人閱讀了很多海內外大神的關於GCD的文章,以及結合之前自己對GCD的粗淺的認識,然後取其精華,去其槽粕,綜合起來的筆記,而且是盡可能的以通熟易懂的並且是正確的理論論述方式呈現給大家,已經是盡可能的讓大家掌握多線程的知識以及GCD的使用技術。最後的附錄中,我將會給出所有本人閱讀的大神寫的關於多線程或者是GCD的文章鏈接,大家感興趣的,可以去參考和學習。

本篇博文:持續更新,還未更新完。

相關基本概念

1、什麼是GCD?

iOS實現提供實現多線程的方案有:NSThread、NSOperation、NSInvocationOperation、pthread、GCD。

在iOS所有實現多線程的方案中,GCD應該是最有魅力的,而且使用起來也是最方便的,因為GCD是蘋果公司為多核的並行運算提出的解決方案。

GCD是Grand Central Dispatch的簡稱,它是基於C語言的。使用GCD,我們不需要編寫線程代碼,其生命周期也不需要我們手動管理,定義想要執行的任務,然後添加到適當的調度隊列,也就是dispatch queue。GCD會負責創建線程和調度任務,系統直接提供線程管理。

2、任務(Task)

一段代碼塊,執行之後能夠實現的一段業務邏輯過程。一般用閉包或者叫block,來包含它。執行任務,就需要將這個閉包或者block交給隊列,然後讓隊列 先進先出(FIFO) 的順序取出來,放進線程中執行。

3、隊列(Queue)

我們需要了解隊列的概念,GCD提供了dispatch queues來處理代碼塊,這些隊列管理所提供給GCD的任務並用FIFO順序執行這些任務。這樣才能保證第一個被添加到隊列裡的任務會是隊列中第一個開始的任務,而第二個被添加的任務將第二個開始,如此直到隊列的終點。

    串行(Serial)隊列

    串行隊列 中的任務會根據隊列定義 先進先出(FIFO) 的順序取出來一個,執行一個,執行完了然後取出下一個任務,這樣一個一個的執行。

    串行隊列圖:

   

    並發(Concurrent)隊列

    並發隊列 中的任務也會根據隊列定義 先進先出(FIFO)的順序一個個取出來,但是與串行隊列不同的是,並發隊列取出一個任務會放到別的線程中開始執行,先不管這個線程是同步線程還是異步線程,並發隊列並不是等線程中的任務執行完了而是取完了這個任務,就會立刻接著從並發隊列中取下一個任務放到別的線程中開始執行。由於取任務的速度很快,忽略不計,看起來,好像所有任務都是同時開始執行任務的。但是,任務又長又短,任務執行結束的順序你是無法確定的,有可能那個最短的任務先執行完畢了。

    並發隊列圖:

   

補充:並發代碼的不同部分可以“同步”執行。然而,該怎樣發生或是否發生都取決於系統。多核設備通過並行來同時執行多個線程;然而,為了使單核設備也能實現這一點,它們必須先運行一個線程,執行一個上下文切換,然後運行另一個線程或進程。這通常發生地足夠快以致給我們並發執行地錯覺,如下圖所示:

  

4、隊列的類型(Queue Types)

系統提供的:

    一個主隊列(main queue),是串行隊列。

    和其它串行隊列一樣,這個隊列中的任務一次只能執行一個。然而,它能保證所有的任務都在主線程執行,而主線程是唯一可用於更新 UI 的線程。這個隊列就是用於發生消息給 UIView 或發送通知的。

  

    在使用主線程串行隊列時,我們只通過dispatch_get_main_queue方法來獲取即可,我們不需要管理其內存問題。

    四個全局調度隊列(Global Dispatch Queues),都是並行隊列

    四個全局隊列有著不同的優先級:background、low、default 以及 high。要知道,Apple 的 API 也會使用這些隊列,所以你添加的任何任務都不會是這些隊列中唯一的任務。

   在使用全局並發隊列時,我們只通過dispatch_get_global_queue方法來獲取即可,我們不需要管理其引用。

    你也可以創建自己的串行隊列或並發隊列。

  

總結:這就是說,至少有五個隊列任你處置:主隊列、四個全局調度隊列,再加上任何你自己創建的隊列。

以上是調度隊列的大框架!

5、線程

  線程分為兩種:Synchronous vs. Asynchronous 同步 vs. 異步。

  GCD創建同步線程和異步線程的方式:

  

  這裡會有兩個東西要說:同步函數和異步函數。我們的C語言基礎就學了函數,函數用大括號包含了一段代碼塊,當這個函數執行完畢就會返回,可以是返回void或者返回具體某個數據值,同時也代表著這個函數的執行完畢。那麼線程中的函數,當然是包含了任務的,這個任務就是閉包或者叫block。同步函數和異步函數的區別就在,同步函數需要在完成了它預定的任務後才返回,而異步函數會立即返回,也就是說異步函數預定的任務會完成但不會等它完成就立即返回。

  另外,同步線程是不具備創建子線程的能力的,一般情況下,同步線程的任務會在唯一的主線程中執行,也就是說唯一的(main)主線程就成了同步線程。而異步線程是具備創建子線程的能力的,一般情況下,異步線程就是(main)主線程以外的線程,不唯一,會有多個,具體多少個,具體是哪些線程,如果是通過GCD創建,全部由GCD決定。關於能創建的子線程的最大個數,這個就需要根據設備的CPU的能力了,比如下面是本人用真機,通過使用GCD創建了多個異步任務,並添加進並發隊列執行測試的結果:

  

  可以發現,我創建了8個異步任務,GCD根據設備的極限,創建了三個子線程,分別是線程2、3、4,然後由它們隨機執行任務。其中線程4執行了四個任務,線程2和線程3分別執行了兩個任務。

  那麼,同步還是異步,這兩個術語是需要多個函數任務之間對比來論述的,這樣會更好理解。比如說同步,當線程執行一個同步函數任務的時候,這個線程會停下來,也就是所謂的"當前這個線程阻塞"了,當前線程需要等待這個函數執行完畢返回了值,也表示這個函數中的任務完全執行完畢了,這個線程才會繼續執行下去,去執行下一個函數任務,所以這樣的線程也叫同步線程。而異步函數所在的線程就不一樣了,線程開始執行一個異步函數任務的時候,因為異步函數立即返回了,雖然這個函數任務可能還沒執行完畢,但是返回了,這個線程就會繼續執行下一個函數任務,由於這個過程很快,快到可以忽略不計任務執行開始的先後順序,快到感覺好像都是同時開始執行任務的,所謂的"異步線程同時執行多個任務"就是這麼來的。

注意:

  不要將耗時操作放在主線程中,凡是跟UI相關的操作都是放在主線中處理

  耗時操作應該放在子線程(後台線程,非主線程)

6、總結一下同時使用隊列和線程

好,下面我們來看看這個圖,可能會和你們別處看的有點不一樣,這是本人根據上面理論進行了適當的修改:

  

6-1、串行隊列+同步:

  假設一堆任務放在串行隊列中。

  因為串行隊列是先進先出FIFO隊列,而且串行隊列是需要前面取出的一個任務執行完了之後,才接著取下一任務。

  因為同步(sync)沒有開啟新線程的能力。

  所以,這一堆任務,將會在main主線程中,一個執行完畢之後接著下一個開始執行直到完畢,就這樣按順序執行任務。

  會阻塞當前線程。

  驗證代碼:

  

  打印結果:

  2016-03-13 15:51:04.970 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}
  2016-03-13 15:51:06.974 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}
  2016-03-13 15:51:08.979 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}
  2016-03-13 15:51:10.980 多線程[25106:632356] 當前線程是:<NSThread: 0x7fe28bc025b0>{number = 1, name = main}

6-2、並發隊列+異步:

6-3、

6-4、

附錄:很好的GCD學習的網頁鏈接

1、GCD這塊已經開源,地址http://libdispatch.macosforge.org

2、唐巧的技術博客:《使用GCD》,地址:http://blog.devtang.com/2012/02/22/use-gcd/

3、大神翻譯自國外IOS很不錯的學習網站文章《Grand Central Dispatch In-Depth: Part 1/2》:https://github.com/nixzhu/dev-blog

4、標哥的技術博客:《GCD由淺入深學習》:http://www.henishuo.com/gcd-multiple-thread-learn/

5、土土哥的《GCD使用經驗與技巧淺談》:http://tutuge.me/2015/04/03/something-about-gcd/

6、YouXianMing老師的《Grand Central Dispatch (GCD) Reference》:http://www.cnblogs.com/YouXianMing/p/3600763.html

7、《關於IOS多線程,你看我就夠了》:http://www.jianshu.com/p/0b0d9b1f1f19

8、《細說GCD(Grand Central Dispatch)如何使用》 :http://www.jianshu.com/p/fbe6a654604c

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved