【问题标题】:check which request is which from NSURLConnection delegate检查哪个请求来自 NSURLConnection 委托
【发布时间】:2012-05-08 15:07:27
【问题描述】:

检查委托方法中哪个请求的最佳方法是:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{

}

现在我有一个 NSURLConnection,我在发出请求之前设置为 NSURLConnection,在 didReceiveResponse 内部我这样做:

if (self.tempConnection == connection)

但是,这有可能不适用于竞争条件。有没有更好的方法来做到这一点?

【问题讨论】:

  • 发布的第二个解决方案实际上是我所做的,但正如我所说......因此存在竞争条件
  • 基本上 self.connectionType == 连接只有在您请求 a 并且委托返回 b 时才有效。如果您向 a 发出一个需要很长时间的请求,然后 b 启动,然后 a 返回.. 那么 self.connectionType == connection 的比较将无效,因为 self.connectionType 是 B 和连接是 A。明白我的意思了吗?

标签: iphone objective-c ios ipad nsurlconnection


【解决方案1】:

在 OS5 中有更好的方法。忘记所有那些烦人的委托消息。让连接为您构建数据,并将您完成的代码与您的起始代码保持一致:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.site.com"]];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    NSLog(@"got response %d, data = %@, error = %@", [httpResponse statusCode], data, error);
}];

【讨论】:

  • 该解决方案仅适用于完成和失败状态。对于进度更新,您仍然需要玩 Find the Instance。
【解决方案2】:

我查看了很多不同的方法来做到这一点,我发现到目前为止,最简洁和最容易管理的是使用块模式。这样,您就可以保证在完成时响应正确的请求,避免竞争条件,并且在异步调用期间变量或对象超出范围不会有任何问题。阅读/维护您的代码也容易得多。

ASIHTTPRequest 和 AFNetworking API 都提供了块模式(但是 ASI 不再受支持,因此最好使用 AFNetworking 来获取新内容)。如果您不想使用这些库之一,但想自己动手,您可以下载 AFNetworking 的源代码并查看它们的实现。然而,这似乎是很多额外的工作,没有什么价值。

【讨论】:

    【解决方案3】:

    考虑创建一个单独的类作为委托。然后,对于每个生成的 NSURLConnection,为该 NSURLConnection 实例化一个委托类的新实例

    这里有一些简短的代码来说明这一点:

    @interface ConnectionDelegate : NSObject <NSURLConnectionDelegate>
    

    ...然后实现.m文件中的方法

    现在,我猜您可能已经在 UIViewController 子类(或其他用于不同目的的类)中发布了代码?

    无论您在哪里启动请求,都可以使用以下代码:

    ConnectionDelegate *newDelegate = [[ConnectionDelegate alloc] init];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"<url here">]];
    [NSURLConnection connectionWithRequest:request delegate:newDelegate];
    
    //then you can repeat this for every new request you need to make
    //and a different delegate will handle this
    newDelegate = [[ConnectionDelegate alloc] init];
    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"<url here">]];
    [NSURLConnection connectionWithRequest:request delegate:newDelegate];
    
    // ...continue as many times as you'd like
    newDelegate = [[ConnectionDelegate alloc] init];
    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"<url here">]];
    [NSURLConnection connectionWithRequest:request delegate:newDelegate];
    

    您可以考虑将所有委托对象存储在 NSDictionary 或其他一些数据结构中以跟踪它们。我会考虑在 connectionDidFinishLoading 中使用 NSNotification 来发布连接完成的通知,并提供从响应创建的任何对象。让我知道您是否需要代码来帮助您将其可视化。希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 2012-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      相关资源
      最近更新 更多