多次使用NSURLConnection

时间:2013-02-26 20:52:01

标签: ios objective-c nsurlconnection nsrunloop nsurlconnectiondelegate

我正在尝试在启动第一个NSURLConnection后启动第二个NSURLConnection。我的第一个工作完美:适当的代表都被调用,一切都按计划执行。但是,在第一个完成后,我创建了第二个,没有任何反应(代理永远不会被调用)。可能会发生什么?我知道我不能重复使用相同的NSURLConnection,但我在重新使用它之前重新初始化它,所以它应该是一个全新的连接。

这是我启动(两个)连接的代码。它是相同的实例变量,但它已重新初始化。另请注意,第二个在第一个完全运行之前不会启动。

if (connection) {
    [connection cancel];
}

currentResponse = nil;
error = nil;

connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO];
if (!connection) {
    NSLog(@"Connection could not be initialized.");
    [self connectionFinished];
} else {
    [connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    [connection start];
}

1 个答案:

答案 0 :(得分:2)

您还没有分享如何“在不同的线程上运行它”,但典型的问题是如果您使用调度队列或操作队列,您的连接本身是异步运行的,因此调度的操作是完成并获得发布,你就失去了联系。

一些可能的解决方案:

  1. 您可以在您的后台操作中同步执行网络操作(这是您应该进行同步网络操作的唯一时间)。这是最简单的解决方案,尽管您尚未解释您对NSURLConnection所做的事情,因此这项技术可能适用于您,也可能不适合您。但是,如果您只是尝试从URL下载某些内容,则可以执行以下操作:

    NSData *data = [NSData dataWithContentsOfURL:url
                                         options:0
                                           error:&error];
    

    如果您需要NSURLConnectionDataDelegate方法,例如质询 - 响应身份验证,或者使用didReceiveData进行流式传输以减少应用内存,则此方法不起作用足迹或性能原因等。但如果您只是尝试从远程服务器下载数据(例如检索图像,XML / JSON提要等),这是最简单的。

  2. 以类似的方式(即您不需要NSURLConnectionDataDelegate方法),但是您要为连接创建一些丰富的NSURLRequest,那么您可以使用sendAsynchronousRequestsendSynchronousRequest

  3. 如果您需要NSURLConnectionDataDelegate来电,可以使用setDelegateQueue(指定NSOperationQueue)或scheduleInRunLoop(指定NSRunLoop) ,它会自动将连接更新分派到适当的队列/ runloop。只需确保使用initWithRequest的{​​{1}}选项startImmediately,设置委托队列或runloop,然后NO连接。如果您绝对需要,可以使用此技术保留start的完整丰富度。

  4. 或者,如果您没有使用操作队列,您还可以保持后台操作处于活动状态,直到连接完成。此方法为您提供后台操作中的同步行为(保持连接活动),同时保留NSURLConnectionDataDelegate方法。 Apple's XMLPerformance Sample演示了这种技术(参见CocoaXMLParser.m和LibXMLParser.m的NSURLConnectionDataDelegate方法),在这里它们启动downloadAndParse然后使用以下构造来保持后台操作处于活动状态直到NSURLConnection方法最终设置NSURLConnectionDataDelegate实例变量:

    done
  5. 我承认,我发现这最后的方法含糊不清,并倾向于其他选择,具体取决于您do { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]; } while (!done); 所需的灵活性和功能。为了让我们提供更有意义的建议,您只需要提供有关(a)您在NSURLConnection方法中所做工作的更多信息; (b)您用于在后台运行代码的技术。

    如需更多选项,也可以随时查看GCD and async NSURLConnection