3

私はいくつかのデータを要求するサーバーを持っています。

特定の名前の画像が存在するかどうかを確認していて、BOOL値(YESまたはNO)を返す必要がありますが、非同期リクエストは終了時にコールバックを呼び出すため、その方法がわかりません。メソッドがかなり前に終了し、BOOL値を返さず、メインスレッドをブロックするため、同期要求を使用しません。

これが私のコードです(私はそれが間違っていることを知っていますが、とにかく私がやりたいことの例を示すためにそれを書きます、私の英語はあまり上手ではないからです):

- (BOOL)imageDoesExistsOnTheServer:(NSString *)imageName {
    BOOL exists;

    NSString * query = [[NSString alloc] initWithFormat:@"request=IMAGE&imageName=%@", imageName];

    DREasyURLRequest * imageExistsRequest = [[DREasyURLRequest alloc] initForSendDataToServerWithURLString:@"http://xxxxx.xxxxx/file.php" query:query];

    [imageExistsRequest sendAsynchronouslyWithCompletionForStringAsResponse:^(NSString *receivedResponse) {
        if ([receivedResponse isEqualToString:@"YES"]) {
            __block BOOL exists = YES;
        } else {
            __block BOOL exists = NO;
        }
    }];

    return exists;
}

(DREasyURLRequestは、コードを保存するために作成したNSMutableURLRequestのサブクラスですが、sendAsynchronouslyWithCompletionForStringAsResponse:は、非同期のNSMutableURLRequestメソッドとまったく同じです。

助けてくれませんか?

PD:わかっています、このコードはとても悪いように見えますが、どうしたらよいかわかりません...

4

2 に答える 2

3

returnブロックはコードによって呼び出されないため、コードに何かを提供するために使用することはできません。代わりに、戻り値について考えるのをやめ、行動について考え始めてください。肯定的な反応が得られたときに何かが起こり、否定的な反応が得られたときに何かが起こりたいと考えています。したがって、これらの動作ごとにメソッドを記述し、ブロック内の適切な場所でそれらを呼び出します。

于 2013-01-04T16:51:19.537 に答える
2

このような値を返すことはできません。この関数は、ブロックの非同期実行が完了するまで待機しません。このような状況を処理するための慣用的なパターンは、制御フローの非同期性を維持し、それに応じてコールバックロジックを実装することです。たとえば、委任を使用するか、画像が存在するかどうかを通知する別のブロックを渡すことができます。

- (BOOL)imageDoesExistsOnTheServer:(NSString *)imageName completion:(void ^(BOOL exists)compl {
    // etc.
    [imageExistsRequest sendAsynchronouslyWithCompletionForStringAsResponse:^(NSString *receivedResponse) {
    if ([receivedResponse isEqualToString:@"YES"]) {
        compl(YES);
    } else {
        compl(NO);
    }
}];

そしてそれをこのように呼びます:

[self imageDoesExistOnTheServer:@"Foo.png" completion:^(BOOL exists) {
    if (exists) {
        // exists
    }
}];
于 2013-01-04T16:53:40.157 に答える