非同期メソッドを同期的に呼び出す

非同期に実行が行われ、処理が終わるとデリゲートuserInfoReceived:forRequest:が呼び出されるメソッド [twitterEngine getUserInformationFor:@"user"] を同期的に実行するためのコード例。

- (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)connectionIdentifier {
    // 参考リンクのコード例では volatile 宣言された変数を素でアクセスしているが、
    // それだと、デリゲート内でのオブジェクト設定(retain)が失敗するため、排他処理とする。
    @synchronized(info) {
        // retainしないとinfoが指すオブジェクトにアクセスできなくなる
        info = [[userInfo objectAtIndex:0] retain];
    }
}

- (void)wait {
    // Autorelease pool を作って置かないと、このスレッド内で確保されるオブジェクトがすべてリークする
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    // ここが同期実行させたい非同期処理メソッド呼び出し
    [twitterEngine getUserInformationFor:@"user"];	
    [[NSRunLoop currentRunLoop] run];
    [pool drain];
}

- (id)waitForMethod {
    // 同期実行したいメソッドを呼び出すスレッドを起動する
    NSThread *th = [[NSThread alloc] initWithTarget:self selector:@selector(wait) object:nil];
    [th start];
    info = nil;
    while (1) {
        [NSThread sleepForTimeInterval:0.1]; // 0.1秒ごとに結果(info)をチェックする
        // 参考リンクのコード例では volatile 宣言された変数を素でアクセスしているが、
        // それだと、デリゲート内でのオブジェクト設定(retain)が失敗するため、排他処理とする。
        @synchronized(info) {
            if (info != nil) break;
        }
    }
    [th cancel];
    [th release];
}

    [self waitForMethod]; // あるメソッド内でこれを呼ぶとメンバ変数 info に値が格納されて戻る

最終更新:2010年02月14日 01:27
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。