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

-> [前回](http://qiita.com/Saayaman/items/e603693a9bf967821e5d)からの続き

## 5. .concurrent属性 / .initiallyinactive属性

DispatchQueueはlabelとqosの他に***attributes***という属性をつけることができる。
**.concurrent**と**.initiallyinactive**の二つがあり、どちらもキューではなく**Work Itemを制御する**ものです。

### A .concurrent

同じ同じキューの中で、Work Itemを同時処理させる属性。(結果は下A図)

```
    let anotherQueue = DispatchQueue(label: "com.ayakosayama.anotherQueue", qos: .utility, attributes: .concurrent)

     func attribuesTest(){

        anotherQueue.async {
            for i in 0..<10{
                print("🔵",i)
            }
        }
        
        anotherQueue.async {
            for i in 100..<110{
                print("🔴",i)
            }
        }
        
        anotherQueue.async {
            for i in 1000..<1010{
                print("⚫️",i)
            }
        }
    }
```

### B .initiallyInactive

WorkItemをキューの中で待機させておく。実行処理を別で書かないと発動しない。(結果は下B図)

```
    var inactiveQueue: DispatchQueue!
    let anotherQueue = DispatchQueue(label: "com.appcoda.anotherQueue", qos: .utility, attributes: .initiallyInactive)
    
    func attribuesTest(){
        
        inactiveQueue = anotherQueue

        anotherQueue.async {
            for i in 0..<10{
                print("🔵",i)
            }
        }
        
        anotherQueue.async {
            for i in 100..<110{
                print("🔴",i)
            }
        }
        
        anotherQueue.async {
            for i in 1000..<1010{
                print("⚫️",i)
            }
        }
    }
```

### 実行メソッド

```
        attribuesTest()
        if let queue = inactiveQueue{
            queue.activate()
        }
```

![Screen Shot 2017-07-11 at 3.14.32 PM.png](https://qiita-image-store.s3.amazonaws.com/0/158705/d50759dd-8367-39db-ae86-20edc3f5ebf5.png)


## 6. global()でフリーなキューをランダムで選ぶ

これまでは自分でカスタムキューを作ってきましたが、システムがバックグラウンドで作ったdispatch queueのコレクション、つまりグローバルキュー(global queues)を使うこともできる。

```
    func globalQueue(){
        let globalQueue = DispatchQueue.global()

        globalQueue.async {
            print(globalQueue.label)  // com.apple.root.default-qos
            for i in 1..<1000{ print("⚫️",i)}
        }
    }
```
この場合は処理が短い&使われてなかったので、デフォルトのQOSが選ばれている。

## 7. delayqueue.asyncaAfter()でキューの遅れる時間を制御する

以下のように、キューの処理を2秒遅らすというプログラムを書いて実行してみます。

```
    func queueWithDelay(){
        print(Date())

        let delayqueue = DispatchQueue(label: "com.ayakosayama.delayqueue", qos: .userInteractive)
        
        let additinalTime:DispatchTimeInterval = .seconds(2)
        delayqueue.asyncAfter(deadline: .now() + additinalTime){
            print(Date())
        }
    }
```
結果：ちょうど2秒遅れてprint(Date)されている！

```
2017-07-11 21:14:13 +0000
2017-07-11 21:14:15 +0000
```

## 8. コールバック関数で、ダウンロード後UIに画像を描画する

```
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var label: UILabel!

    func fetchImage(){
        label.text = "downloading..."
        let imageURL: URL = URL(string: "https://worldstrides.com/wp-content/uploads/2015/07/12-Chureito-pagoda-and-Mount-Fuji-Japan.jpg")!

        (URLSession(configuration: URLSessionConfiguration.default)).dataTask(with: imageURL, completionHandler: { (imageData, response, error) in
            
            if let data = imageData {
                
                DispatchQueue.main.async {
                    self.label.text = "finished downloading!"
                    self.imageView.image = UIImage(data: data)
                }
            }
        }).resume()
    }

```

imageViewに画像を表示させたい！という処理ですが、
UIに表示させるコマンド(imageview.image = UIImage(data:data))が画像ダウンロード前に実行されると、ダウンロードが終わっても表示されない！

そこで上記のように、                
DispatchQueue.main.async {}で覆ってあげるとよい。

![downloading.gif](https://qiita-image-store.s3.amazonaws.com/0/158705/41d89031-4f4a-3f04-dab2-4bd30e1ab4f3.gif)


おしまい！

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