制作线程NSURLConnections

时间:2013-05-03 23:27:22

标签: ios objective-c multithreading nsurlconnection

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

下面,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];
}

1 个答案:

答案 0 :(得分:1)

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

  1. 使用其中一个非委托替代方案。如果您在后台执行此操作,则可以使用sendSynchronousRequest,或者如果只是从简单网址请求数据,则可以使用NSData类方法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):

      • NSThread电话创建专用的NSURLConnectionDataDelegate;

      • 在该线程上启动NSRunLoop;

      • 使用与上述startImmediately:NO init方法相同的NSURLConnection版本;以及

      • scheduleInRunLoop之前使用NSURLConnection的{​​{1}}选项。

    • 或者,最简单的方法是,您可以使用AFNetworking

  3. 两个观察结果:

    1. 我可能倾向于使用操作或调度队列而不是start。请参阅Concurrency Programming Guide

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

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