2

foo:バックグラウンド スレッドで呼び出されるメソッドがあります。このメソッドは単純にリクエストをサーバーに送信し、データが取得された後、それらのデータに関する計算を実行して戻ります。この場合、私はsendSynchronousRequest: を使用することを好みます。この方法は便利で、スレッドがブロックされていても問題にならないからです。ただし、応答には、別のページにリダイレクトする "Location" ヘッダー フィールドが含まれています。リダイレクトの前に、これらの「Set-Cookie」ヘッダー フィールドを取得するために応答を読みたいと思います。同期メソッドでは許可されていないようです。

非同期のものを使用して を実装しようとしましたNSURLConnectionDataDelegateが、デリゲートのメソッドが呼び出される前にスレッドが終了します。(Appleが非同期のものを実装する方法は、時間のかかる作業を新しいスレッドで実行することだと思います)

この問題を解決する方法はありますか? メインスレッドで非同期リクエストを実行すると、プログラムが複雑になる可能性があります。

foo: メソッドはこのようなものです

- (Result *)foo
{
    NSURLMutableRequest * request = blablabla;
    //Do something to initialize the request
    NSData *data = [NSURLConnection sendSynchronousRequest:request 
                                         returningResponse:&response
                                                     error:&error];

    //Do something with the data

    Result *result = [[Result alloc] init] autorelease];
    //fill the result

    return result;
}
4

4 に答える 4

3

Grand Central Dispatch セマフォを使用して、非同期リクエストが返されるまで待機できます。

- (Result *)foo
{
    NSMutableURLRequest * request = [[NSMutableURLRequest alloc] init];
    // set request's properties here

    __block Result *result;
    dispatch_semaphore_t holdOn = dispatch_semaphore_create(0);
    [NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        if (error)
        {
            //  handle error
        }
        else
        {
            result = [[Result alloc] initWithData:data];
        }
        dispatch_semaphore_signal(holdOn);
    }];

    dispatch_semaphore_wait(holdOn, DISPATCH_TIME_FOREVER);

    return result;
}

注:このコードには、iOS 4.0 以降と ARC が必要です。

于 2013-04-11T09:21:08.250 に答える
0

これを可能にする小さくて単純なクラスをgithubで見つけることができます。NSOperationsQueue マネージャとバックグラウンド フェッチを実行するように設計された NSOperation サブクラスの 2 つの主要なオブジェクトを提供します。前述のとおり、フェッチだけを行っていた場合は、メイン スレッドで実行できます。ただし、データ処理も行いたい場合は、このプロジェクトを使用すると、完成したメソッドでそれを行うことができます.

OperationsRunner クラスの優れた特性は、いつでも操作をキャンセルできることです (たとえば、ユーザーが [戻る] ボタンをタップしたとき)。

ただし、この1回のフェッチと1つのプロセスだけを行う場合は、他の人が言ったように、メインスレッドでデータをフェッチし、それを取得したら、「処理」ブロックを並行システムスレッドの1つにディスパッチすることができます、その処理が完了すると、作業が完了したことを知らせる別のメッセージをメイン スレッドにディスパッチします。

于 2013-04-11T12:30:20.363 に答える