最近遇到被一个问题折腾惨了,后来终于解决,这里记录一下。
问题现象:
JSON解析失败,报错如下:
可又不是每次都失败,有些时候又会成功。
刚开始怀疑所JSON的格式错了,但为什么有时候会成功呢?
于是怀疑所有些数据里面可能保护\n,\r等字符,影响了解析。可是加入了转义甚至替换之后,该问题还是没解决,陷入了困境。
难道所因为数据被截断了?
没办法,只能打日志进行调试,发现:
//实现获取到数据的委托方法
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"length: %d", [data length]);
}
发现data的内容有时候为8520,有时候又是4536和3984。
果然,数据真的被截断,被分成了两部分返回。
于是开始找答案,发现当异步请求返回数据过大时,didiReceiveData这个代理函数所会调用多次的,应该使用connectionDidFinishLoading函数,把数据接收完全后进行处理。
解决代码如下:
1、在.h文件里面加入变量来接收数据
@property(strong, nonatomic) NSMutableData *recvData;
2、在didiReceiveData这个委托方法里面获取接收的数据进行存储
//实现获取到数据的委托方法
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"length: %d", [data length]);
[self.recvData appendData:data];
}
3、加入connectionDidFinishLoading函数,在这个函数中完成数据解析
//获取到全部数据后,进行数据解析
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:self.recvData options:NSJSONReadingMutableLeaves error:&error];
if (json == nil) {
[self doneLoadingTableViewData];
NSLog(@"json parse failed. \n error is: %@", error);
return;
}
NSString *result = [json objectForKey:@"result"];
if ([result boolValue]) {
//to do
}
}
总结:
对于非常少量的数据,可以在didiReceiveData里面写接收数据后的处理逻辑,对于请求大量数据的场景,切记,一定要在connectionDidFinishLoading中,对接收完全的数据进行处理。