1

最初のNSURLConnectionを開始した後、2番目のNSURLConnectionを開始しようとしています。私の最初のものは完璧に機能します。適切なデリゲートがすべて呼び出され、すべてが計画どおりに実行されます。ただし、最初のものが終了した後、2番目のものを作成しても、何も起こりません(デリゲートが呼び出されることはありません)。何が起こっているのでしょうか?同じNSURLConnectionを再利用できないことはわかっていますが、再利用する前に再初期化するので、完全に新しい接続である必要があります。

これが(両方の)接続を開始するための私のコードです。これは同じインスタンス変数ですが、再初期化されています。また、最初のものが完全に実行を終了するまで、2番目のものは開始されないことに注意してください。

if (connection) {
    [connection cancel];
}

currentResponse = nil;
error = nil;

connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
if (!connection) {
    NSLog(@"Connection could not be initialized.");
    [self connectionFinished];
} else {
    [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [connection start];
}
4

1 に答える 1

2

「別のスレッドで」実行する方法を共有していませんが、一般的な問題は、ディスパッチキューまたは操作キューを使用している場合、接続自体が非同期で実行されているため、ディスパッチされた操作が完了して取得していることです。解放され、接続が失われます。

考えられる解決策のいくつか:

  1. このバックグラウンド操作でネットワーク操作を同期的に実行できます(同期ネットワーク操作を実行する必要があるのはこれが唯一の場合です)。これは最も簡単な解決策ですが、で何をしているのかを説明していないNSURLConnectionため、この手法が機能する場合と機能しない場合があります。ただし、URLから何かをダウンロードしようとしているだけの場合は、次のことができます。

    NSData *data = [NSData dataWithContentsOfURL:url
                                         options:0
                                           error:&error];
    

    NSURLConnectionDataDelegateこのアプローチは、チャレンジレスポンス認証などの方法を必要とするもう少し複雑な場合やdidReceiveData、アプリのメモリフットプリントを削減するために、またはパフォーマンス上の理由でストリーミングを使用している場合などには機能しません。リモートサーバーからデータをダウンロードしようとするだけで(たとえば、画像、XML / JSONフィードの取得など)、これが最も簡単です。

  2. 同様に(つまり、メソッドは必要ありません)、接続用にNSURLConnectionDataDelegateリッチを作成している場合は、またはのいずれかを使用できます。NSURLRequestsendAsynchronousRequestsendSynchronousRequest

  3. NSURLConnectionDataDelegate呼び出しが必要な場合は、 setDelegateQueue(を指定するNSOperationQueue)またはscheduleInRunLoop(を指定するNSRunLoop)を使用すると、接続の更新が適切なキュー/実行ループに自動的にディスパッチされます。のオプションをinitWithRequest使用し、デリゲートキューまたは実行ループを設定してから、接続を設定してください。このテクニックを使用すると、絶対に必要な場合の完全な豊かさを維持できます。startImmediatelyNOstartNSURLConnectionDataDelegate

  4. または、操作キューを使用していない場合は、接続が完了するまでバックグラウンド操作を維持することもできます。このアプローチにより、メソッドを維持しながら、バックグラウンド操作(接続を維持)で同期動作が可能になりますNSURLConnectionDataDelegate。この手法は、AppleのXMLPerformanceサンプルdownloadAndParseCocoaXMLParser.mおよびLibXMLParser.mのメソッドを参照)によって示されます。ここで、を開始し、次の構成を使用して、メソッドがインスタンス変数を設定するNSURLConnectionまでバックグラウンド操作を維持します。NSURLConnectionDataDelegatedone

    do {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
                                 beforeDate:[NSDate distantFuture]];
    } while (!done);
    

私は、この最終的なアプローチが漠然と不満であり、必要な柔軟性と機能に応じて、他の選択肢に傾倒することを認めますNSURLConnection。私たちがより意味のある助言を提供するためには、あなたは(a)あなたがあなたのNSURLConnectionDataDelegate方法で行っている仕事の種類についてより多くの情報を提供する必要があります。(b)コードをバックグラウンドで実行するために使用しているテクノロジー。

その他のいくつかのオプションについては、 GCDと非同期NSURLConnectionもお気軽にご覧ください。

于 2013-02-27T05:30:14.527 に答える