2016-09-08 8 views
-1

私はAFNetworkingライブラリを使用しているブロックvoid関数を作成しました。この機能は、GETリクエストで使用され、そのように使用されます。iOSはブロックが完了するまでブロックします

[Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
    //use response here 
}]; 

すべてがうまく動作しますが、たとえば、値を返す必要のある関数でこのブロックを使用すると頭痛が発生します。

+ (NSArray*)OnlineClients 
{ 
    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
    }]; 

    return clients; 
} 
OnlineClients

配列の機能要求ブロックは完了して終了していないので、常に0アイテムを返します。

ブロック補完が関数の返り値として返されるのを待つ方法はありますか?

私はStackOverflowとgoogleでさまざまなトピックを検索していますが、解決策は見つかりませんでした。

助けてください。

+1

あなたは非常によく検索していません。これは、スタックオーバーフローに関するiOSプログラミングのすべてで、おそらく最もよく聞かれる質問です。 – matt

+0

[iOS:API完了ブロックを待って結果を返す]の重複している可能性があります(http://stackoverflow.com/questions/23507331/ios-waiting-for-api-completion-block-and-returning-the-result) – HAS

+0

http://stackoverflow.com/a/23507361/1489885 – HAS

答えて

1

あなたの問題に対処する方法はいくつかあります。 dispatch_groupまたはdispatch_semaphoreを使用して、戻り値の前に非同期呼び出しからの応答を待機するか、応答をコールバックするブロックを持つようにメソッドを変更できます。以下のコードをご覧ください。 Dispatch_groupとdispatch_semaphoreは、別のスレッドが信号をトリガするまで待つように現在のスレッドをブロックすることに注意してください。したがって、スレッドをメインスレッドで使用しないでください。私の意見では、私は第3の解決策を提案します。 私はそれがあなたを助けてくれることを願っています。

//1 
+ (NSArray*)OnlineClients 
{ 
    dispatch_group_t serviceGroup = dispatch_group_create(); 

    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
     dispatch_group_leave(serviceGroup); 
    }]; 

    dispatch_group_enter(serviceGroup); 

    return clients; 
} 

//2 
+ (NSArray*)OnlineClients 
{ 
    dispatch_semaphore_t sema = dispatch_semaphore_create(0); 

    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
     dispatch_semaphore_signal(sema); 
    }]; 

    dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); 

    return clients; 
} 

//3 
+ (void)getOnlineClientsWithCompletionBlock:(void (^) (NSArray *clients))completionBlock 
{ 
    NSString *clientsUrlStr = [NSString stringWithFormat:@"%@/sinch/clients", ROOT_URL]; 
    __block NSArray *clients = [[NSArray alloc] init]; 
    [Mics getRequestBLOCK:clientsUrlStr BlockRequest:^(NSString *response) { 
     clients = [response componentsSeparatedByString: @","]; 
     if (completionBlock) { 
      completionBlock(clients); 
     } 
    }]; 

} 
+0

1と2はスレッドをブロックすることになります。メインスレッドでUIインタラクションをブロックしようとすると、それがブロックされます。それに言及すると有益かもしれない。 – sbarow

+0

@sbarow正確に。あなたの点をありがとう、スレッドのブロックの期間に注意する必要があります。 – HDT

+0

まずは、ありがとうございます。解決策1:これは何も待たず、配列はまだ '0要素'を返します。正直なところ私はこれを試しましたが、動作しません。解決策2:私が前にこれをしたようにこのコードを適用すると、これは永遠に待っていて、決して戻ることはありません。 – vietnguyen09

関連する問題