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

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

## 1. キューとGCDの単語集

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

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

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

![Screen Shot 2017-07-11 at 1.23.16 AM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/be7e6c26-8427-6483-95ef-3eee62560d1e.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](https://qiita-image-store.s3.amazonaws.com/0/158705/00e4a179-1cc6-f82c-8e2d-d781c1058b85.png)



## 4. Quality を変更して処理スピードを制御する
DispatchQueueは **"label"**の他に**"qos"(Quality of Service:処理速度)**を決めることができる。[こちらのドキュメント](https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/PrioritizeWorkWithQoS.html)によると、QOSは4段階あって、スピードは以下です。

![Screen Shot 2017-07-11 at 12.22.34 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/0f7a57c3-067d-3e46-7754-ee710e3df8ab.png)

選べないQOSが実は2つほどあり、DefaultとUnspecifiedで、速さは以下です。
![Screen Shot 2017-07-11 at 2.09.32 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/2ad7ab67-6138-875d-e89e-af4e5c85b2ad.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](https://qiita-image-store.s3.amazonaws.com/0/158705/68f00bdb-aff8-bb55-a013-32131fd8df04.png)


[2回目はGCDのGlobal()とDelay()とコールバック関数についてまとめます！](http://qiita.com/Saayaman/items/59371bb8dc97f1d21e62)

元ネタ[こちら](https://www.appcoda.com/grand-central-dispatch/)！
Gihtubコードは[こちら](https://github.com/Saayaman/i0S/tree/master/GCD)！