使用sendAsynchronousRequest:queue:completionHandler:iOS 5方法建立多个NSURLConnections和

使用sendAsynchronousRequest:queue:completionHandler:iOS 5方法建立多个NSURLConnections和,ios,networking,nsurlconnection,nsoperationqueue,http-request,Ios,Networking,Nsurlconnection,Nsoperationqueue,Http Request,设置与sendAsynchronousRequest:queue:completionHandler:方法(NSURLConnectionclass)相关的正确配置有一些困难 我的设想如下: 我建立了一个单例类,它管理不同的NSURLConnections。此单例istance有一个NSOperation队列(称为downloadQueue),它向web服务器发出请求并检索字符串路径(1)。 完成后,该路径用于下载web服务器中的文件(2)。最后,当文件被正确下载后,我需要更新UI(3) 我只找

设置与
sendAsynchronousRequest:queue:completionHandler:
方法(
NSURLConnection
class)相关的正确配置有一些困难

我的设想如下:

我建立了一个单例类,它管理不同的
NSURLConnection
s。此单例istance有一个
NSOperation队列
(称为
downloadQueue
),它向web服务器发出请求并检索字符串路径(1)。 完成后,该路径用于下载web服务器中的文件(2)。最后,当文件被正确下载后,我需要更新UI(3)

我只找到了第一个请求:我可以通过它下载路径。你能给我建议一个执行另外两个步骤的方法吗

这里有几个问题:

  • 下载队列(
    downloadQueue
    )不是主队列,是否可以在该队列中打开新的NSURLConnection?换句话说,这是正确的吗?(请参见代码段中的注释)

  • 如果前面的问题是正确的,我如何获取主队列并更新UI

在这里,我使用代码片段来执行第一步,
downloadQueue
是一个实例变量,可以通过访问器方法(
@property
/
@syntheticed
)获得


就我所知,要更新ui,必须在主线程上进行。可以从其他线程更新ui,但这些更新并不完全可靠。在我组装的一个向web服务发出请求的应用程序中,我使用dispatch_async()访问主队列,然后从该调用中更新表视图

dispatch_async(dispatch_get_main_queue(), ^{
    //block to be run on the main thread
    [self.tableView reloadData];
});

我希望这会有所帮助。

您的第一次下载是正确的

在第一次下载后的完成处理程序块中,您正在计算第二次下载所需的URL,对吗?然后,您可以使用相同的方式执行第二次下载:使用新URL和相同的队列再次调用
+[NSURLConnection sendAsynchronousRequest:…]
。您可以在第一次下载的完成块中执行此操作

要在第二次下载完成后更新UI,请切换到该下载的完成块内的主队列。您可以使用
dispatch\u async()
dispatch\u sync()
(在这种情况下,这并不重要,因为您在下载队列上没有进一步的工作要做)和
dispatch\u get\u main\u queue()
,或者使用
-[NSOperationQueue addOperationWithBlock:
+[NSOperationQueue mainQueue]

您的代码应该如下所示:

// init download queue
downloadQueue = [[NSOperationQueue alloc] init];    

// (1) first download to determine URL for second
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[self downloadQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if([data length] > 0 && error == nil) {
        // set newURLRequest to something you get from the data, then...
        // (2) second download
        [NSURLConnection sendAsynchronousRequest:newURLRequest queue:[self downloadQueue] completionHandler:^(NSURLResponse *newResponse, NSData *newData, NSError *newError) {
            if([newData length] > 0 && newError == nil) {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    // (3) update UI
                }];
            }
        }];
    }
}];

+谢谢你的支持。你能解释一下为什么我可以使用相同的队列来执行第二次呼叫吗?谢谢。这是一个队列:您对其进行的操作以先进先出的顺序执行。因此,如果您在第一个操作的执行过程中将另一个操作排队(并且在第一个操作的主要工作——下载——完成之后),那么第二个操作将在第一个操作之后。这回答了你的问题吗?(我不确定你在“为什么它会工作”这方面想要什么。如果你说为什么你认为它不会工作,回答起来可能会更容易。)我有一个类似的问题,不同的是在第一次下载时我得到了很多URL,所以我通过for循环发送多个异步请求,我试图实现上面的代码,但它不起作用。我做错了什么?@Edu:在一个新问题中发布更多详细信息,我们将看看我们能做些什么来提供帮助。NSOperationQueue只有在其maxConcurrentOperationCount设置为1时才是串行的。默认情况下,NSOperationQueue是动态系统情况允许的并发队列。感谢您的回复。我提出的问题是关于在sendAsynchronousRequest中执行另一个请求:队列:completionHandler:。换句话说,我想知道如何使用上述方法执行一系列请求。干杯
// init download queue
downloadQueue = [[NSOperationQueue alloc] init];    

// (1) first download to determine URL for second
[NSURLConnection sendAsynchronousRequest:urlRequest queue:[self downloadQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    if([data length] > 0 && error == nil) {
        // set newURLRequest to something you get from the data, then...
        // (2) second download
        [NSURLConnection sendAsynchronousRequest:newURLRequest queue:[self downloadQueue] completionHandler:^(NSURLResponse *newResponse, NSData *newData, NSError *newError) {
            if([newData length] > 0 && newError == nil) {
                [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                    // (3) update UI
                }];
            }
        }];
    }
}];