1

我有一个 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];

Content-Length 永远不会在 http 标头中设置。当请求失败时,download_size 为 -1(预期),当同一请求未失败时,download_size 设置为某个数字。但是,有很多情况下download_size没有设置,响应也没有失败。

4

2 回答 2

1

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

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

好吧,我当然希望那些是 20 个不同的self对象。您不能指望这会与单个对象同时充当所有 20 个请求的委托!

于 2013-04-03T16:17:51.270 回答
1

这不是发起 20 个请求的好方法,因为:

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

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

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

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

  • 如果您想要并发操作(并且这样做有明显的性能优势),您可以使用NSOperationQueue并发操作,但使用maxConcurrentOperationCount. 如果您在这些后台操作中使用同步网络操作,这个过程是微不足道的,但是如果您在后台队列中使用带有自己的委托方法的异步网络操作,那么这个过程会非常复杂。

  • 如果您确实需要 (a) 使用您自己的委托方法使用异步网络调用(例如更新进度视图、流协议等);AFNetworking(b) 如果您想享受并发操作,那么使用它会比编写您自己的操作容易得多。我经历了自己的写作练习,但是在完成了一次练习之后,我现在更充分地了解AFNetworking了桌面上的内容。

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

于 2013-04-03T18:17:09.837 回答