iOSのマルチスレッドGrand Central Dispatch(GCD)をまとめ


1.What is GCD?
非同期処理
```
dispatch_async(queue,^
{
    // Do some thing here.
});
```


2.Dispatch Queue
Queueを作成
Serial Dispatch Queue:Single thread，
Concurrent Dispatch Queue:Multi thread for example download process etc.。
Serial Dispatch Queue:

```
dispatch_queue_t serialDispatchQueue = dispatch_queue_create("com.example.queue.serial",NULL);
dispatch_async(serialDispatchQueue,^
{
});
dispatch_release(serialDispatchQueue);
```

Concurrent Dispatch Queue:

```
dispatch_queue_t concurrentDispatchQueue = dispatch_queue_create("com.example.queue.concurrent",DISPATCH_QUEUE_CONCURRENT);
dispatch_async(concurrentDispatchQueue,^
{
});
dispatch_release(concurrentDispatchQueue);
```


2.1 Main Dispatch Queue
Main Dispatch Queue is a Serial Dispatch Queue。

```
dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();
```

2.2 Global Dispatch Queue

```
dispatch_queue_t globalDispatchQueueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);
dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_queue_t globalDispatchQueueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW,0);
dispatch_queue_t globalDispatchQueueBkg = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND,0);
```

2.3 Main and Global example.

```
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^()  
{  
    //Run in global thread controlled by OS.
    dispatch_async(dispatch_get_main_queue(),^()  
    {  
        //Run in main thread
    });  
});
```

3.GCDのAPI example.
3.1 dispatch_after

```
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW,(int64_t)(3.0f*NSEC_PER_SEC));  
dispatch_after(time,dispatch_get_main_queue,^()  
{  
    //Process will be done after 3 second.
}); 
```

3.2 dispatch_once
シングルトンクラスの初期化
```
static dispatch_once_t token;  
dispatch_once(&token,^()  
{  
});
```

3.3 Dispatch Group

dispatch_group_notify非同期：

```
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);  
dispatch_group_t group = dispatch_group_create();  
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock1"); });  
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock2"); });  
  
dispatch_group_notify(group,dispatch_get_main_queue(),^{ NSLog(@"Done"); });  
```

dispatch_group_wait同期：

```
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);  
dispatch_group_t group = dispatch_group_create();  
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock1"); });  
dispatch_group_async(group,queue,^{ NSLog(@"TestBlock2"); });  
  
dispatch_group_wait(group,DISPATCH_TIME_FOREVER);  
NSLog(@"Done");  
```

3.4 dispatch_sync
同期
```
dispatch_queue_t queue = dispatch_get_main_queue();  
dispatch_async(queue,^  
{  
    dispatch_sync(queue,^{ NSLog(@"block"); });  
});
```

3.5 dispatch_apply

```
dispatch_apply(10,queue,^(size_t index)  
{  
    NSLog(@"%zu",index);  
});  
NSLog(@"Done");
```

3.6 dispatch_barrier_async
Mainly deal with Concurrent Dispatch Queue to control the process step.
```
dispatch_queue_t queue = dispatch_queue_create(@"ConcurrentDispatchQueue",DISPATCH_QUEUE_CONCURRENT);  
dispatch_async(queue,Block1ForReading);  
dispatch_async(queue,Block2ForReading);  
dispatch_async(queue,Block3ForReading);  
dispatc_barrier_async(queue,BlockForWriting);  
dispatch_async(queue,Block4ForReading);  
dispatch_async(queue,Block5ForReading);  
dispatch_async(queue,Block6ForReading);  
dispatch_release(queue);
```
3.7 dispatch_set_target_queue
優先度変更
```
dispatch_queue_t myQueue = dispatch_queue_create(@"myQueue",0);  
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0);  
dispatch_set_target_queue(myQueue,globalQueue); 
```

3.8 dispatch_suspend / dispatch_resume
Dispatch Queueの停止と復元
```
dispatch_suspend(queue);
dispatch_resume(queue);
```

3.9 Dispatch Semaphore
This is a manually way to control the process step.
```
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);  
dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER); // Set semaphore -1
dispatch_semaphore_signal(semaphore); // Set semaphore +1
```

参考：
http://blog.csdn.net/joywii/article/details/23041195
https://github.com/mixi-inc/iOSTraining/wiki/8.2-Grand-Central-Dispatch