2017年1月4日 星期三

iOS筆記:Swift3 GCD

Grand Central Dispatch (GCD)

在iOS當中,蘋果提供兩個方法來實作多工任務:包含Grand Central Dispatch (GCD)以及NSOperationQueue的frameworks,它們都可以幫助開發者達到多個任務分配給多個執行緒或不同queues進行同步運行的需求.

主佇列都是用來處理UI接收到的指令,所以跑在主執行緒的任務是最優先執行的
有時候都會在completion handler block執行以下的方式來更新UI, 主要的原因是因為原本的狀況並不是在main queue刷新UI介面, 所以可能你的圖片已經下載好了 但礙於不是在main queue所以會沒辦法及時被更新而產生很多error log.

    DispatchQueue.main.async {
        self.imageView.image = UIImage(data: data)
    }

GCD在swift上一直都是基於C建立的, 之前也有聽人說過如果把swift上跟dispatch相關的程式碼貼到linux上可以直接運作. 但這件事情在Swift 3上應該是不會再發生了. 因為這方面進行了大改版. 詳細的部分請參考Reference.

Dispatch framework

  1. DispatchQueue
    取代原本Dispatch async的工能, 建立一個queue最基本的語法:

        let queue = DispatchQueue(label: "dispatchQueue")

    queue一旦被建立後,我們就可以透過程式碼使用它,同步則使用sync函式,若非同步則呼叫async函式,當我們開始時,先提供一段code當做一個block(closure).

            queue.async {
            for _ in 1...10 {
                print("111111111")
            }
        }
  2. DispatchQoS (Quality of Service)
    可以去決定執行緒的權重(優先順序), 右邊為Swift 3現在的語法, 左邊則是對應到之前的權限是多大. 根據想要的優先順序,提供一個適當的QoS值在佇列初始化作業,如果沒有特別定義,佇列則預設為 default priority.

    enter image description here

    測試的話可以先定義兩條queue然後再用forloop看執行結果就可以明顯看出優先權高跟低的差異.

    let queue1 = DispatchQueue(label: "com.appcoda.queue1", qos: DispatchQoS.userInitiated)
let queue2 = DispatchQueue(label: "com.appcoda.queue2", qos: DispatchQoS.utility)
  1. DispatchWorkItem
    DispatchWorkItem是一個代碼塊(可以想成是把closure封裝成一個item),可以在任何的佇列上面被調用,因此,裡面的程式碼可以在背景執行,或是在主執行緒運行.

        //workItem的目的是將value變量的值增加5
        func useWorkItem() {
            var value = 10
    
            let workItem = DispatchWorkItem {
                value += 5
            }
        }
    
        //調用方式
        let queue = DispatchQueue.global()
        queue.async {
            workItem.perform()
        }

另外也有比較快的方式可以調用work item,DispatchQueue類別為此目的提供了一種方便的方法:

    queue.async(execute: workItem)
  1. DispatchTime 延遲時間
    now()方法會回傳目前時間,另外再把想要延遲的時間添加進來.
    func dispatchTime() {
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) { 
            //兩秒後才會被執行
            print("兩秒了")
        }
    }

Reference:
1. http://www.appcoda.com.tw/grand-central-dispatch/

沒有留言:

張貼留言