【问题标题】:cancel NSURLConnection in ios在 ios 中取消 NSURLConnection
【发布时间】:2015-10-24 07:17:21
【问题描述】:

我正在mapViewdrag/regionChange 上调用 web 服务。我想在 Web 服务调用中保持一些延迟。所以我希望每当用户多次拖动地图时,应该取消所有以前的 Web 服务调用,并且只应该触发最后一次拖动 Web 服务调用。

我该怎么做?

以下是我的代码:

{ .... NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
        [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
        [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];

        NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[data length]];

        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setHTTPBody:data];

        [request setHTTPMethod:@"POST"];
        NSMutableDictionary __block *dictResponse;
    [[NSOperationQueue mainQueue] cancelAllOperations];
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

            if(connectionError == nil){

                dictResponse = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&connectionError];
                }

【问题讨论】:

  • github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/… 自己尝试AFNetworking。我认为这就是您所需要的
  • 顺便说一句,你永远不想在主队列上调用cancelAllOperations。它没有按照您在此处的意图进行,并且您无法保证某些其他任务向主队列添加了一些操作。此外,您无需指定请求的 Content-Length,因为这是自动为您完成的。

标签: ios nsmutableurlrequest


【解决方案1】:

您无法取消sendAsynchronousRequest。如果您使用了基于委托的NSURLConnection 请求,那么您可以取消它,但是(a)这比您可能想要打扰的编码更多; (b) NSURLConnection 已被弃用,所以无论如何你都应该是 NSURLSession; (c) NSURLSession 允许您使用返回给您的 NSURLSessionTask 引用取消任务:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPBody:data];
[request setHTTPMethod:@"POST"];

NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if (error) {
        NSLog(@"connection error = %@", error);
        return;
    }
    NSError *parseError;
    NSDictionary *responseObject = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&parseError];
    if (!responseObject) {
        NSLog(@"parse error = %@", parseError);
    }
    dispatch_async(dispatch_get_main_queue(), ^{
        // use response here; e.g., updating UI or model objects
    });
}];
[task resume];

如果您需要取消此请求,请致电[task cancel]。因此,如果您想跟踪它并在以后取消它,请将这个 NSURLSessionTask 保存在某个弱变量中。

【讨论】:

  • 这是一个很好的解决方案。
  • @Rob - 我遇到了另一个问题。当我取消会话任务并再次请求时,我收到错误代码 -999 并且未发出请求。
  • 当您取消 NSURLSessionTask 时,您应该会看到以错误 -999 调用的完成闭包(即 NSURLErrorCancelled)。当您创建一个新的NSURLSessionTask 时,将再次调用闭包。确保您没有将第一个响应与第二个响应混淆。
【解决方案2】:

不要使用sendAsynchronousRequest 便利API,使用主委托API,这样您就可以访问NSURLConnecyion 的实例来调用cancel

另外,不要取消主队列上的操作,你不知道里面有什么,考虑使用NSURLSession

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-19
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多