ios - NSURLConnection sendAsynchronousRequest 没有得到响应

标签 ios objective-c nsurlconnection nsurlrequest

我有一个创建 NSURLRequest 的方法,并使用 NSURLConnection 方法 sendAsynchronousRequest:queue:compltionHandler: 发送该请求。当我获取 json 文件或图像数据时,这工作得很好,但是当我尝试获取 XML 文档时,会发生一些非常奇怪的事情。该方法正在被调用,但从未有响应,因此从未调用完成处理程序。有谁知道如何解决这一问题?我已经使用这种方法数百次了,但我从未见过这种行为。这是我调用 sendAsynchronousRequest:queue:compltionHandler:

的方法
- (void)getCachedFile:(NSString *)title withCompletion:(void (^)(NSData *data))completion
{
    Reachability *reach = [Reachability reachabilityForInternetConnection];
    NetworkStatus status = [reach currentReachabilityStatus];
    if (status == NotReachable)
    {
        // read data locally
        NSError *error = nil;
        NSData *data = [NSData dataWithContentsOfFile:[self filePath:title]
                                              options:NSDataReadingUncached
                                                error:&error];
        if (error)
        {
            NSLog(@"COULD NOT READ LOCAL CACHED DATA: %@", error.localizedDescription);
        }
        else
        {
            completion(data);
        }
    }
    else
    {
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:title]
                                                 cachePolicy:NSURLRequestUseProtocolCachePolicy
                                             timeoutInterval:30.0f];

        // get data from NSURLCache
        NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
        if (cachedResponse)
        {
            // if the data is found in the response, use it
            completion([cachedResponse data]);
        }
        else
        {
            // get the data from the server
            [NSURLConnection sendAsynchronousRequest:request
                                               queue:[NSOperationQueue currentQueue]
                                   completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                                       if (connectionError)
                                       {
                                           NSLog(@"ERROR CONNECTING DATA FROM SERVER: %@", connectionError.localizedDescription);
                                       }
                                       else
                                       {
                                           [self.writingOperationQueue addOperationWithBlock:^{
                                          [[NSFileManager defaultManager] createFileAtPath:[self filePath:title]
                                                                                  contents:data
                                                                                attributes:nil];
                                           }];
                                           completion(data);
                                       }
                                   }];
        }
    }
}

最佳答案

一般来说有一些注意事项: 网络请求的完成 block 正在捕获self。这将导致循环引用。

^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    if (connectionError)
    {
        NSLog(@"ERROR CONNECTING DATA FROM SERVER: %@", connectionError.localizedDescription);
    } else {
        [self.writingOperationQueue addOperationWithBlock:^{
            [[NSFileManager defaultManager] createFileAtPath:[self filePath:title]
                                                    contents:data
                                                  attributes:nil];
        }];
        completion(data);
    }
}

要修复此问题,您应该在 block 之前声明一个变量 __weak MyClass *weakSelf = self; 并且仅在 block 内使用该变量。

您的具体问题可能与您正在调用的文档类型无关,更多地与您从哪个线程调用它有关。您正在 [NSOperationQueue currentQueue] 上执行网络操作。如果这是一个系统队列,它可能会在您的请求完成之前被释放。您应该声明一个 NSOperationQueue 属性并在其上执行所有网络请求。

[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue currentQueue]
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {...}];

应改为:

[NSURLConnection sendAsynchronousRequest:request
                                   queue:self.networkOpQueue
                       completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {...}];

关于ios - NSURLConnection sendAsynchronousRequest 没有得到响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21418292/

相关文章:

ios - UITextField 上的强密码覆盖

ios - 解析 iOS SDK 本地化

iphone - 如何在 iPad App 中绘制带发光效果的线条

ios - 在同步调用上强制NSUrlConnection超时

ios - NSURLSession 将 token 发送回服务器以获取数据

javascript - iOS 上滚动问题的粘滞元素

ios - 代码中的 XCode 基础 SDK 版本

ios - 如何获取 iOS 应用程序的 wordpress 客户端 ID 和客户端密码?

objective-c - 无法获得管理员权限。错误域=CFErrorDomainLaunchd 代码=2 "The operation couldn’ 无法完成。 (CFErrorDomainLaunchd 错误 2。)

ios - 多个 NSURLConnection 是否创建多个线程?