1

我正在尝试在启动第一个 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];
}
4

1 回答 1

2

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

几个可能的解决方案:

  1. 您可以在您的这个后台操作中同步执行您的网络操作(这是您唯一应该执行同步网络操作的时间)。这是最简单的解决方案,尽管您还没有解释您在做什么NSURLConnection,所以这种技术可能适合您,也可能不适合您。但如果你只是想从 URL 下载一些东西,你可以这样做:

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

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

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

  3. 如果您需要NSURLConnectionDataDelegate调用,您可以使用setDelegateQueue(指定 a NSOperationQueue)或scheduleInRunLoop(指定 a NSRunLoop),它会自动将连接更新分派到适当的队列/运行循环。只需确保initWithRequest使用startImmediately选项NO,设置委托队列或运行循环,然后start设置连接。NSURLConnectionDataDelegate使用这种技术,如果您绝对需要它,您可以保留完整的丰富性。

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

    do {
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
                                 beforeDate:[NSDate distantFuture]];
    } while (!done);
    

我承认我发现这种最终方法有点不满意,并且会倾向于其他替代方案,这取决于您需要从NSURLConnection. 为了让我们提供更有意义的建议,您只需要提供有关 (a) 您在NSURLConnectionDataDelegate方法中所做的工作类型的更多信息;(b) 您使用哪种技术在后台运行代码。

对于更多选项,也可以随意查看GCD 和 async NSURLConnection

于 2013-02-27T05:30:14.527 回答