Author

2 posts

非同期処理の完了を待ちたい。Delegateで

使っていたとあるライブラリのバージョンアップでとある処理が同期処理から非同期処理に変わっていた。

-(bool)nanikasuruyo{
    Nanigashi *_nanigashi = [Nanigashi alloc] init];
    if(![nanigashi connect]){
        例外!
    }
    return [nanigashi do];
}

こんな感じだったのに。

nanikasuruyoの実装クラスがfactoryで生成されてるのもあって、
そうそう形も変えられないので、
block渡しも却下。

というわけでこうする。

- (void)didConnected{
    dispatch_semaphore_signal(_semaphore);
}
- (bool)nanikasuruyo{
    Nanigashi *_nanigashi = [Nanigashi alloc] init];
    nanigashi.delegate = self;
    _semaphore = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queur(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
        [nanigashi connect];
    });
    dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);

    return [nanigashi do];
}

で動くと思ったら、
didConnectedがメインスレッドで呼ばれるらしくデッドロックになる。。。

https://blog.katty.in/2370
こちらがとても参考になった。

というわけで。

- (void)didConnected{
    dispatch_semaphore_signal(_semaphore);
}
- (bool)nanikasuruyo{
    Nanigashi *_nanigashi = [Nanigashi alloc] init];
    nanigashi.delegate = self;
    _semaphore = dispatch_semaphore_create(0);
    dispatch_async(dispatch_get_global_queur(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),^{
        [nanigashi connect];
    });
    
    while(dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_NOW)){
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
    }
    return [nanigashi do];
}

こうして解決。ちょっと感動。