You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从NSUrlConnection迁移至NSUrlSession时GET请求的两类异常问题咨询

从NSURLConnection切换到NSURLSession的问题解决思路

嘿,我之前在从NSURLConnection迁移到NSURLSession时也踩过类似的坑,给你拆解下这两个问题的解决办法:

问题1:DidReceiveData返回的数据被截断

这其实是NSURLSession的正常行为——didReceiveData:会被多次调用,每次返回的只是当前接收到的部分数据,而不是整个响应体。你不能直接用单次回调里的NSData来处理,必须把这些片段拼接起来,直到请求完成。

解决步骤:

  1. 在你的类中声明一个可变数据容器,用来存储所有接收到的片段:
@property (nonatomic, strong) NSMutableData *totalReceivedData;
  1. 在发起请求前初始化这个容器:
// 初始化数据任务前
self.totalReceivedData = [NSMutableData data];
  1. 在didReceiveData:中拼接数据:
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [self.totalReceivedData appendData:data];
    // 这里不要尝试解析数据!等全部接收完再处理
}
  1. 在请求完成的回调中处理完整数据:
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if (!error) {
        // 这里的totalReceivedData就是完整的响应内容
        NSString *fullResponseString = [[NSString alloc] initWithData:self.totalReceivedData encoding:NSUTF8StringEncoding];
        // 接下来用这个完整字符串处理XML解析
    } else {
        NSLog(@"请求出错: %@", error.localizedDescription);
    }
    // 清空容器,避免影响下一次请求
    self.totalReceivedData = nil;
}

问题2:处理数据时DidCompleteWithError被调用且error为null

这也是NSURLSession的设计逻辑:didCompleteWithError:是请求生命周期的结束回调,不管请求成功还是失败都会触发。当error为null时,说明请求已经成功完成,所有数据都已经通过didReceiveData:传递完毕了。

你之前可能误解了这个方法的作用——它不是只有出错时才会调用,而是用来通知你请求已经结束,是时候处理最终结果(或者错误)的地方。正确的流程就是:在didReceiveData:中只做数据拼接,在didCompleteWithError:中做最终的解析和业务处理。

额外注意事项

  • 如果你的XML解析需要完整的数据源,推荐使用NSXMLParser,把拼接好的totalReceivedData传给它,不要尝试用部分数据解析,否则会导致XML格式错误。
  • 确保你的NSURLSession配置合理,比如设置了足够长的超时时间,避免大响应体还没接收完就被判定超时。

内容的提问来源于stack exchange,提问作者Tobe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:07:10