NSURLConnection connectionDidFinishLoading不随机调用

时间:2013-04-03 16:08:14

标签: ios nsurlconnection

我有一个iPad应用程序,我使用NSURLConnection进行异步调用。在某些情况下,我会在 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

问题的一个奇怪症状是我开始使用以下方式检查预期的内容长度:

long long download_size =[response expectedContentLength];

内容长度永远不会在http标头中设置。当请求失败时,download_size为-1(预期),当同一请求未失败时,download_size将设置为某个数字。但是,在许多情况下,未设置download_size且响应不会失败。

2 个答案:

答案 0 :(得分:1)

我希望你在这里使用单独的对象。你在说

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

嗯,我当然希望这些是20个不同的self个对象。您不能指望这可以同时使用单个对象作为所有20个请求的委托!

答案 1 :(得分:1)

这不是启动20个请求的好方法,因为:

  1. 请求同时运行,因此如果您没有某个类封装来自各个请求的所有响应数据等,您的应用可能会混淆各种请求的响应数据;

  2. 因为它们同时发生并且因为iOS仅允许对给定服务器的五个并发请求,所以它将延迟(并且可能超时)其他服务器。

  3. 你有很多不同的方法,但你可能会:

    • 您可能希望在后台队列中执行此网络操作;

    • 如果您想要并发操作(并且这样做可以获得可观察到的性能优势),您可以使用NSOperationQueue进行并发操作,但要限制正在进行的并发操作数量(到4或5)使用maxConcurrentOperationCount。如果您在这些后台操作中使用同步网络操作,则此过程非常简单,但如果您在后台队列中使用异步网络操作和自己的委托方法,则会非常复杂。

    • 如果您确实需要(a)使用您自己的委托方法来使用异步网络调用(例如更新进度视图,流协议等); (b)您希望享受并发操作,使用AFNetworking比编写自己的操作要容易得多。我经历了自己编写的练习,但是一旦完成了这个练习,我现在更完全理解AFNetworking带来的内容。

    当然,您可以通过管理自己的待处理网络请求数组,启动第一个网络请求并让connectionDidFinishLoading和/或didFailWithError启动下一个网络请求来解决所有问题。队列,但你失去了并发性能。但这是一个简单的解决方法。