1

当我的应用程序启动时,我有很多连接,所以我想把它们放在后台线程上,这样我就可以在它们全部完成之前建立新的连接,而不是开始连接。

下面threadedRequest:是一个启动 NSURLConnection 的方法,但是当我performSelectorInBackground:withObject:if子句中调用时,连接开始了,但永远不会结束。该else子句工作正常并从连接返回数据

if (background)
{
    [self performSelectorInBackground: @selector(threadedRequest:) withObject: args];
}
else
{
    [self performSelector: @selector(threadedRequest:) onThread: [NSThread mainThread] withObject: args waitUntilDone: NO];
}
4

1 回答 1

1

如果要NSURLConnection在后台执行,则必须对适用NSURLConnectionDataDelegate于后台线程中的方法的特殊条件敏感。你有几个选择:

  1. 使用非委托替代方案之一。鉴于您在后台执行此操作,您可以使用sendSynchronousRequest,或者如果只是从简单的 URL 请求数据,您可以使用NSDataclass method dataWithURL

  2. 如果您确实需要委托版本(因为您需要通过didReceiveData或因为您需要其中一种NSURLConnectDelegate方法进行身份验证等来更新进度,您有几个基本选项:

    • 您可以为连接创建NSOperationQueue并设置委托队列。例如,而不是:

      - (void)startConnection:(NSURL *)url
      {
          NSURLRequest *request = [NSURLRequest requestWithURL:url];
          [NSURLConnection connectionWithRequest:request delegate:self];
      }
      

      你可以这样做:

      - (void)startConnection:(NSURL *)url
      {
          NSURLRequest *request = [NSURLRequest requestWithURL:url];
          NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
          [connection setDelegateQueue:self.connectionDelegateQueue];
          [connection start];
      }
      
    • 或者,您可以执行AFNetworking所做的事情(参见AFURLConnectionOperation.m,示例实现):

      • NSThreadNSURLConnectionDataDelegate来电创建专用;

      • NSRunLoop在该线程上启动一个;

      • 使用与上述相同startImmediately:NONSURLConnectioninit 方法;和

      • 使用之前的scheduleInRunLoop选项。NSURLConnectionstart

    • 或者,最简单的,你可以使用AFNetworking

两个观察:

  1. 我可能倾向于使用操作或调度队列而不是performSelectorInBackground. 请参阅并发编程指南

  2. 顺便说一句,您应该知道 iOS 可以同时执行多少并发NSURLConnection请求是有限制的(我相信是 5 或 6 个)。因此,如果你发起了十几个后台请求,然后发起了一个“前台”请求,那么“前台”请求可能不会立即启动。如果要避免此潜在问题,您可能希望限制可以同时操作的后台请求的数量。

    就个人而言,当我想限制网络请求的数量时,我将我的后台请求添加到 aNSOperationQueue并设置最大并发操作数(例如我一般使用 4),享受并发操作的好处,同时不尝试执行更多并发比 iOS 允许的连接。顺便说一句,在使用操作队列的maxConcurrentOperations功能时,您必须确保请求是同步的(或者将异步连接包装在自定义NSOperation中,直到连接完成或失败才会终止)。

于 2013-05-04T08:16:35.187 回答