0

このメソッドを、「request startWithCompletionHandler」ブロックがその要求と独自のブロック内のコードを完了するまで完了しないブロックにするにはどうすればよいですか?

順番に呼び出す必要がある一連のブロックがありますが、それらはすべてリクエストを送信するためのコードを必要とします。タスクを達成するためのクリーンな方法を見つけようとしています。

+(void)???????? ^block()
{
    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
        ....
    }];
}

追加情報: はい、内側の関数が完了するまで外側の関数を待機させたい

ありがとう。

4

3 に答える 3

1

それはあなたが何を意味するかによって異なります。サンプルコードを考えると、ネストされたブロックが完了すると、関数がブロックを呼び出すように思われます。したがって、次のようなものが必要です。

+ (void)doMyThingWithBlock:(void(^)(void))block
{
    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {

        // do whatever you want with the connection ...

        if (block) block();

    }];
}

一方、外側の関数は、ネストされたブロックが完了するまで待ってから戻るようにしたい場合があります。その場合は、もう少し複雑です。次のように、ブロックが完了するのを待つためにロックを使用する必要があります。

#define kMyThingNotDone 0
#define kMyThingDone    1

+ (void)doMyThingAndWait
{
    NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:kMyThingNotDone];

    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {

        // do whatever you want with the connection ...

        [lock lock];
        [lock unlockWithCondition:kMyThingDone];

    }];

    [lock lockWhenCondition:kMyThingDone];
    [lock unlock];
}

注意してください。メイン スレッドでこれを実行したくない場合は、ユーザー インターフェイスをロックしてください。また、これを呼び出すスレッドで何かが発生するのをリクエストが待機しないようにする必要があります。そうしないと、デッドロックが発生します。

于 2013-04-05T08:13:42.593 に答える
-1

Facebook のような API を使用すると、リクエストにかかる時間 (ネットワーク条件の変更 / エンドの負荷 / ....) を事前に知ることはできないため、スレッド ロック / 待機は使用しません。

メソッドにブロックを渡す場合(他のブロックをカプセル化して順次実行することもできます):

+(void) getFacebookDataWithCompletion:(void (^)(<some parameters))completion {

    FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey];
    [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {

       if (!error)
       {
           //Do your thing with the facebook result (update user info, ....)
       }
       if (completion)
       {
           //Now that you have what you need from fb run your block(s) 
           completion(<params>);
       }

    }];
  }
于 2013-04-05T08:55:03.953 に答える
-1

要求を順番に実行することが唯一の要件であり、FBRequest がそれを実行しない場合 (私は API に精通していません)、1 つのオプションは、それらの呼び出しをシリアル キューにラップすることです。

dispatch_queue_t mySerialQueue = dispatch_queue_create("com.mycompany.serializedrequests", NULL);
dispatch_async(mySerialQueue, ^{
   FBRequest *request = [FBRequest requestForGraphPath:kFacebookQueryMeKey];
   [request startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error) {
    ....
   }];
});
于 2013-04-05T08:10:19.057 に答える