1

NSURLConnection を使用して非同期呼び出しを行っている iPad アプリケーションがあります。場合によっては、connection:didReceiveData:ですべての応答データを受け取りますが、connectionDidFinishLoading が呼び出されることはありません。エラーはありません。同じ応答が他の時点で完了するため、これは多少ランダムです。

私のクラスの仕組みは、次を使用して約 20 のリクエストが連続して送信されることです。

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];

そして、彼らが戻ってくるのを待つだけです。これは複数のリクエストを作成する有効な方法ですか?

完了しなかった応答のサンプル ヘッダーを次に示します。完了した応答のヘッダーと見分けがつきません。

>Keep-Alive: timeout=5, max=100
>Transfer-Encoding: Identity
>Server: Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.8b mod_jk/1.2.26
>Content-Type: application/json;charset=UTF-8
>Connection: Keep-Alive
>Date: Wed, 03 Apr 2013 05:25:32 GMT
>Cache-Control: private, no-transform, max-age=600

問題の奇妙な症状の 1 つは、予想されるコンテンツの長さを次のようにチェックし始めたことです。

long long download_size =[response expectedContentLength];

Content-Length が http ヘッダーに設定されることはありません。リクエストが失敗した場合、download_size は -1 (予想) です。同じリクエストが失敗しなかった場合、download_size は何らかの数値に設定されます。ただし、download_size が設定されておらず、応答が失敗しない場合が多くあります。

4

2 に答える 2

1

これは、次の理由から、20 個のリクエストを開始するのに最適な方法ではありません。

  1. リクエストは同時に動作するため、個々のリクエストからのすべてのレスポンス データなどをカプセル化するクラスがない場合、アプリはさまざまなリクエストからのレスポンス データを混乱させる可能性があります。

  2. これらは同時に発生し、iOS では特定のサーバーに対して 5 つの同時要求しか許可されないため、他の要求が遅延 (および場合によってはタイムアウト) します。

さまざまなアプローチがありますが、おそらく次のようになります。

  • このネットワーク処理をバックグラウンド キューで実行したい場合があります。

  • 同時操作が必要な場合 (そしてそうすることで目に見えるパフォーマンス上の利点がある場合)、 を使用NSOperationQueueして同時操作を行うことができますが、 を使用して進行中の同時操作の数を (4 または 5 に) 制限しますmaxConcurrentOperationCount。このプロセスは、これらのバックグラウンド操作で同期ネットワーク操作を使用している場合は簡単ですが、バックグラウンド キューで独自のデリゲート メソッドを使用して非同期ネットワーク操作を使用している場合は驚くほど複雑です。

  • (a) 独自のデリゲート メソッドを使用して非同期ネットワーク呼び出しを使用する必要がある場合 (進行状況ビューの更新、ストリーミング プロトコルなど)。(b)並行操作を楽しみたい場合は、独自に作成するよりもはるかに使いやすくなりAFNetworkingます。私は自分で書くというこの練習をしましたが、その練習を一度やったAFNetworkingので、テーブルに何がもたらされるかをより完全に理解するようになりました.

確かに、保留中のネットワーク リクエストの独自の配列を管理し、最初のリクエストを開始して、キュー内の次のリクエストを実行または開始することで、これらすべてを回避できますが、同時実行によるパフォーマンスの向上は失われますconnectionDidFinishLoadingdidFailWithErrorしかし、これは 1 つの簡単な回避策です。

于 2013-04-03T18:17:09.837 に答える
1

ここで別のオブジェクトを使用することを願っています。あなたが言っています

NSURLConnection *connection = 
  [[NSURLConnection alloc] initWithRequest:request 
     delegate:self startImmediately:YES];

selfそうですね、それらが 20 個の異なるオブジェクトであることを願っています。これが、20 個すべてのリクエストのデリゲートとして機能する単一のオブジェクトで同時に機能するとは考えないでください。

于 2013-04-03T16:17:51.270 に答える