2009-05-05 11 views
1

私のiPhoneアプリケーションコードは現在NSURLConnection sendSynchronousRequestを使用しています。接続の進行状況とキャッシングの可視性が必要な場合を除いて正常です。非同期NSURLConnectionに移動します。NSURLConnection - 完了を待つ方法

非同期コードが完了するのを待つ最も簡単な方法は何ですか?それをNSOperation/NSOperationQueue、performSelector ...で囲むか、それとも何ですか?

ありがとうございました。

答えて

4

今後誰かがこの問題にぶつかる場合に備えて、私はこれに答えています。 AppleのURLCacheサンプルコードは、これがどのように行われたかの良い例です。 /待機をブロックしない - - 通知ジョンは上記のコメントで指摘するように

:あなたはでそれを見つけることができます。

2

NSURLConnectionを非同期で使用するには、initWithRequest:delegate:でデリゲートを初期化します。デリゲートは、NSURLConnectionデリゲートメソッドを実装する必要があります。 NSURLConnection処理は別のスレッドで行われますが、デリゲートメソッドは、関連するNSURLConnectionオブジェクトの非同期読み込み操作を開始したスレッドで呼び出されます。

+0

こんにちは、 よろしいですか。しかし、私が取り組んでいるビットは、要求が完了するまで他のスレッドで待つ/ブロックする方法です。 ありがとうございます。 – denton

+3

@dentonあなたはブロックしたくありません。要求が完了すると、メイン(または他の)スレッドに通知します。 NSNotificationCenterは1つの方法です。 –

2

前述の通知の他に、一般的な方法として、URLのロード完了を知る必要のあるクラスに、URLコールバックを処理するクラスの代理人として設定する方法があります。 URLのロードが完了すると、デリゲートが呼び出され、ロードが完了したことが伝えられます。

実際には、スレッドをブロックすると、同じスレッドで動作するため、接続は決してどこにも行きません(はい、非同期メソッドを使用していても)。

2

このアプリケーションでは、NSURLConnection sendSynchronousRequestというかなりの場所で、処理を完了するために余分なデータを必要とするバックグラウンドスレッドで何らかの処理が行われているなどの理由でこの問題が発生しました。このような何か:

// do some processing 
NSData * data = someCachedData; 
if (data = nil) { 
    data = [NSURLConnection sendSynchronousRequest....] 
    someCachedData = data; 
} 
// Use data for further processing 

あなたは十分な大きさのコードベースを持っている場合は、別の関数にそれを壊すことはなんとか望ましい(または単にないではないかもしれない、それを行うと同じ流れで3つの別の場所のようなものを持っている場合)。

SSL証明書のピン割り当てを行うために、私たちは接続の代理人を必要としました。私はソリューションのためにインターネットを動かしていました。すべての形式は次のようなものでした。「単に非同期を使用し、フレームワーク! "

ここケースでは誰もが、私が行ったように見てくる投稿
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse *__autoreleasing *)response error:(NSError *__autoreleasing *)error 
{ 
    static NSOperationQueue * requestsQueue; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     requestsQueue = [[NSOperationQueue alloc] init]; 
     requestsQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount; 
    }); 

    NSCondition * waitLock = [NSCondition new]; 
    [waitLock lock]; 

    __block NSError * returnedError; 
    __block NSURLResponse * returnedResponse; 
    __block NSData * returnedData; 
    __block BOOL done = NO; 
    [NSURLConnection sendAsynchronousRequest:request 
             queue:requestsQueue 
          completionHandler:^(NSURLResponse * response, NSData * data, NSError * connectionError){ 

        returnedError = connectionError; 
        returnedResponse = response; 
        returnedData = data; 
        [waitLock lock]; 
        done = YES; 
        [waitLock signal]; 
        [waitLock unlock]; 
       }]; 
    if (!done) { 
     [waitLock wait]; 
    } 
    [waitLock unlock]; 
    *response = returnedResponse; 
    *error = returnedError; 
    return returnedData; 
} 

:まあ、sendSynchronousRequestはこれが基本となる非同期接続でそれを再現する方法である理由のために存在します。

NSURLConnection sendAsynchrounousRequestは、代理人などでNSURLConnectionオブジェクトを作成するなど、非同期要求の送信に使用する方法に置き換えることができます。

+0

すばらしいコードありがとう –

関連する問題