dispatch_sync

dispatch_syncを使う

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // メインスレッドで非同期実行
    NSLog(@"1.%@", [NSThread isMainThread]? @"mainThread": @"backgroundThread");
    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 第一引数でキューを指定して同期実行
        NSLog(@"2.%@", [NSThread isMainThread]? @"mainThread": @"backgroundThread");
    });
    return YES;
}

結果

2015-03-04 00:00:00.393 BlockTest[87419:20719139] 1.mainThread // 当然
2015-03-04 00:00:00.632 BlockTest[87419:20719139] 2.mainThread
 // え?

dispatch_syncのクイックリファレンス

Submits a block object for execution on a dispatch queue and waits until that block completes.
Submits a block to a dispatch queue for synchronous execution. Unlike dispatch_async, this function does not return until the block has finished. Calling this function and targeting the current queue results in deadlock.
Unlike with dispatch_async, no retain is performed on the target queue. Because calls to this function are synchronous, it "borrows" the reference of the caller. Moreover, no Block_copy is performed on the block.
As an optimization, this function invokes the block on the current thread when possible.

Calling this function and targeting the current queue results in deadlock

とのことで、dispatch_syncの第一引数をdispatch_get_main_queue()にするとdeadlockすることは確認した。

挙動を見る

2つ目のNSLogにブレークポイントを貼ってスレッドを見ると挙動がわかる。

とりあえずそういうものだと納得。