LoginSignup
58
48

More than 5 years have passed since last update.

GCD(Grand Central Dispatch)でキューの順番とスピードを制御する方法(1/2)

Last updated at Posted at 2017-07-11

Grand Central Dispatch (GCD) とはAppleが用意したマルチタスクを簡単に行うための方法です。簡単にまとめると、タスクをスレッド分けするのが超便利なフレームワークだよ★
タスクが多くなってきて、別スレッドが必要になった時にどちらも有効です。

1. キューとGCDの単語集

キューとは?

同期通信(synchronously)と非同期通信(asynchronously)にタスクがこなせるコードのブロックです。メインスレッドでもサブスレッドでも行える。
キューはデータ項目の先入れ先出し(FIFO: First In/First Out)の仕組みです。

work itemとは?

Dispatch Queueが実行するタスクのことです。Queueの初期化時に作られる場合もあれば、あとでQueueにアサインされるともある。また再利用も可能。

キューはSerial(一列)もしくはConcurrent(コンカレント/並列)にタスクが実行できる。Serial はWork Item(タスク)が終わってからのWork Itemを実行し、ConcurrentはWork Itemが並列に実行される。

Screen Shot 2017-07-11 at 1.23.16 AM.png

2. DispatchQueueでキューを作ってみよう

func simpleQueues(){
      let queue = DispatchQueue(label: "com.ayakosayama.simpleQueue")
        queue.sync {
            for i in 0..<10{
                print("💜",i)
            }
        }

        for i in 100..<110{
            print("💛",i)
        }
}

DispatchQueue(label:)でQueueを初期化する。label:で名前もつけることができる。これを実行すると💜x 10 -> 💛 x 10 の運番で実行される。メインスレッドが同期通信(sync)なので、どちらもメインスレッドで実行されています。(下図1)

3. DispatchQueue()でAsync(非同期通信)をしてみよう

func asyncQueues(){

        let queue = DispatchQueue(label: "com.ayakosayama.myqueue1")
        let queue2 = DispatchQueue(label: "com.ayakosayama.myqueue2")

        queue.async {
            for i in 0..<10{
                print("🔵",i)
            }
        }

        queue2.async {
            for i in 100..<110{
                print("🔴",i)
            }
        }

        for i in 1000..<1010{
            print("⚫️",i)
        }
    }

下図2をみると、タスク三つがほぼ同じスピードで処理されていることがわかります。

Screen Shot 2017-07-11 at 12.02.45 PM.png

4. Quality を変更して処理スピードを制御する

DispatchQueueは "label"の他に"qos"(Quality of Service:処理速度)を決めることができる。こちらのドキュメントによると、QOSは4段階あって、スピードは以下です。

Screen Shot 2017-07-11 at 12.22.34 PM.png

選べないQOSが実は2つほどあり、DefaultとUnspecifiedで、速さは以下です。
Screen Shot 2017-07-11 at 2.09.32 PM.png

前回と同じ赤、青、黒ボールをprintするという3つの処理をしてみましょう。

func queueWithQos(){

        queue.async {
            for i in 0..<10{
                print("🔵",i)
            }
        }

        queue2.async {
            for i in 100..<110{
                print("🔴",i)
            }
        }

        for i in 1000..<1010{
            print("⚫️",i)
        }
}

User-initiated VS Utility

let queue = DispatchQueue(label: "com.ayakosayama.myqueue1", qos: .userInitiated)
let queue2 = DispatchQueue(label: "com.ayakosayama.myqueue2", qos: .utility)

Background vs User-Interactive

let queue = DispatchQueue(label: "com.ayakosayama.myqueue1", qos: .background)
let queue2 = DispatchQueue(label: "com.ayakosayama.myqueue2", qos: .userInteractive)

図3は、⚫️がメインスレッドなので、一番先に処理されて、🔵user-instantiatedの方が、🔴Utilityより処理が早いことがわかります。

図4では、🔴User-interactiveが⚫️メインスレッドとほぼ同じスピードで処理されていることがわかります。🔵Backgroundは何があっても、一番処理が遅いです。

Screen Shot 2017-07-11 at 12.07.50 PM.png

2回目はGCDのGlobal()とDelay()とコールバック関数についてまとめます!

元ネタこちら
Gihtubコードはこちら

58
48
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
58
48