Swift-GCD,

來源:互聯網
上載者:User

Swift-GCD,

本篇文章介紹的是在Swift3語言下的GCD應用操作,針對的目標讀者可以是沒有GCD基礎的初學者,也可以是對GCD有一定的瞭解但想更加全面的瞭解開發人員。

一、GCD 介紹
  • 背景

在 iOS 當中,蘋果提供了兩種方式進行多任務編程:Grand Central Dispatch (GCD) 和 NSOperationQueue。當我們需要把任務分配到不同的線程中,或者是非主隊列的其它隊列中時,這兩種方法都可以很好地滿足需求。選擇哪一種方法是很主觀的行為,但是本教程只關注前一種,即 GCD。不管使用哪一種方法,有一條規則必須要牢記:任何操作都不能堵塞主線程,必須使其用於介面響應以及使用者互動。所有的耗時操作或者對 CPU 需求大的任務都要在並發或者後台隊列中執行。

GCD 是在 iOS 4 中推出的,它為並發、效能以及並行任務提供了很大的靈活性和選擇性。但是在 Swift 3 之前,它有一個很大的劣勢:由於它的編程風格很接近底層的 C,與 Swift 的編程風格差別很大, API 很難記,即使是在 Objective-C 當中使用也很不方便。這就是很多開發都避免使用 GCD 而選擇 NSOperationQueue 的主要原因。簡單地百度一下,你就能瞭解 GCD 曾經的文法是怎麼樣的。

Swift 3 中,這些都有了很大的變化。Swift 3 採用了全新的 Swift 文法風格改寫了 GCD,這讓開發都可以很輕鬆地上手。而這些變化讓我有了動力來寫這篇文章,這裡主要介紹了 Swift 3 當中 GCD 最基礎也最重要的知識。如果你曾經使用過舊文法風格的 GCD(即使只用過一點),那麼這裡介紹的新風格對你來說就是小菜一碟;如果你之前沒有使用過 GCD,那你就即將開啟一段編程的新篇章。

  • GCD 概念

    • 隊列

    首先,GCD 中的核心詞是 dispatch queue。一個隊列實際上就是一系列的代碼塊,這些代碼可以在主線程或後台線程中以同步或者非同步方式執行。一旦隊列建立完成,作業系統就接管了這個隊列,並將其分配到任意一個核心中進行處理。不管有多少個隊列,它們都能被系統正確地管理,這些都不需要開發人員進行手動管理。隊列遵循 FIFO 模式(先進先出),這意味著先進隊列的任務會先被執行(想像在櫃檯前排隊的隊伍,排在第一個的會首先被服務,排在最後的就會最後被服務)。

    • 任務

    接下來,另一個重要的概念就是 WorkItem(任務項)。一個任務項就是一個代碼塊,它可以隨同隊列的建立一起被建立,也可以被封裝起來,然後在之後的代碼中進行複用。正如你所想,任務項的代碼就是 dispatch queue 將會執行的代碼。隊列中的任務項也是遵循 FIFO 模式。這些執行可以是同步的,也可以是非同步。對於同步的情況下,應用會一直堵塞當前線程,直到這段代碼執行完成。而當非同步執行的時候,應用先執行任務項,不等待執行結束,立即返回。我們會在後面的執行個體裡看到它們的區別。

    • 串列、並行

    瞭解完上面兩個概念(隊列和任務項)之後,我們需要知道一個隊列可以是串列或並行的。在串列隊列中,一個任務項只有在前一個任務項完成後才能執行(除非它是第一個任務項),而在並行隊列中,所有的任務項都可以並存執行。

    在為主隊列新增工作時,無論何時都要加倍小心。這個隊列要隨時用於介面響應以及使用者互動。並且記住一點,所有與使用者介面相關的更新都必須在主線程執行。如果你嘗試在後台線程更新 UI,系統並不保證這個更新何時會發生,大多數情況下,這會都使用者帶來不好的體驗。但是,所有發生在介面更新前的任務都可以在後台線程執行。舉例來說,我們可以在從隊列,或者後台隊列中下載圖片資料,然後在主線程中更新對應的 image view。

    • 全域隊列

    我們不一定需要每次都建立自己的隊列。系統維護的全域隊列可以用來執行任何我們想執行的任務。至於隊列在哪一個線程運行,iOS 維護了一個線程池,即一系列除主線程之外的線程,系統會從中挑選一至多條線程來使用(取決於你所建立的隊列的資料,以及隊列建立的方式)。哪一條線程會被使用,對於開發人員來說是未知的,而是由系統根據當前的並發任務,處理器的負載等情況來進行“決定”。講真,除了系統,誰又想去處理上述的這些工作呢。

  • 初步認識

    • 建立一個個隊列
    // 建立了一個標籤是”queue0“、執行優先順序為.default的並行隊列let queue0 = DispatchQueue(label: "queue0", qos: .default, attributes: .concurrent)// 屬性解釋:// label:隊欄標籤// qos:設定隊列的優先順序// attributes:隊列形式:預設串列,設定為.concurrent代表是並行隊列// 這個初始化方法中還有兩個參數,但我們極少使用這裡就不多介紹建立一個簡單的串列隊列(不設定優先權)let queue1 = DispatchQueue(label: "queue1")
    • 建立一個有優先順序的串列隊列
    let queue2 = DispatchQueue(label: "queue2", qos: .background)
    • 建立一個並行隊列
    // 未設優先順序let queue3 = DispatchQueue(label: "queue3", attributes: .concurrent)// 設定了優先順序let queue4 = DispatchQueue(label: "queue4", qos: .background,attributes: .concurrent)
    • 系統的全域隊列
    // 系統的全域隊列let queue5 = DispatchQueue.global()let queue6 = DispatchQueue.global(qos: .default)
    • 系統的主隊列
    // 系統主隊列:切記這主要用來操作UI頁面相關資訊,不要隨便添加耗時任務進來let main = DispatchQueue.main
GCD 串列
  • 串列同步任務
override func viewDidAppear(_ animated: Bool) {   super.viewDidAppear(animated)      queueExample()}    func queueExample() {      // 串列隊列   let queue1 = DispatchQueue.global()      // 同步任務   // 任務1   queue1.sync {       for i in 1...10 {           print("

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.