我在点击按钮时调用服务器,连接didReceiveData
返回Null
并崩溃应用程序。但是有一个if
- else
条件来检查数据是否为Null
,并在if
条件下再次启动服务器调用,这是最佳做法吗?
-(IBAction)btnClicked:(id)sender
{
NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:url];
[storeRequest setHTTPMethod:@"POST"];
[storeRequest setValue:@"application/json" forHTTPHeaderField:@"Accept"];
[storeRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[storeRequest setValue:postLength forHTTPHeaderField:@"Content-Length"];
[storeRequest setHTTPBody:postData];
NSURLConnection *theConnection;
theConnection =[[NSURLConnection alloc] initWithRequest:storeRequest delegate:self];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data1
{
if (data1==nil)
{
[self downloadDetails];//Restart the download
}
else
{
receivedData =[[NSMutableData alloc]init];
[receivedData appendData:data1];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError* error;
NSMutableArray* jsonArray = [NSJSONSerialization
JSONObjectWithData:receivedData
options:kNilOptions
error:&error];
[appDelegate.inboxArray addObjectsFromArray:jsonArray];
}
答案 0 :(得分:0)
receivedData需要是一个实例变量,因此它具有在委托方法调用之间持续存储的持续时间。一种常见的模式是在其getter中使用延迟实例化(使其成为“私有”@property
)。
现在你拥有它的方式,如果你获得了多个块,你就会消灭以前的块(而不是让其他任何东西访问你的数据)。
我只能假设您正在实施其他委托方法......
答案 1 :(得分:0)
在回答您关于是否应该在失败时立即重新启动请求的问题是一个好习惯时,答案是否定的。如果你想重试,你应该:
只有在另一个请求有合理的成功机会的情况下才会这样做(例如,它没有因为完全缺乏网络连接而失败;只有在Reachability类的实现告诉你后,你才会重试重新建立网络连接);
采用“最大重试次数”逻辑,以确保将重试次数限制为合理的数量(例如,您不想用尽用户的数据计划,关注设备性能,用户体验等) ;
在重试之前加入一些延迟(例如,如果您的服务器没有响应,因为它被请求淹没,用不间断的请求流来攻击它将无济于事);以及
如果连接失败并且用户将应用程序返回到前台,则启动该过程(例如,常见的情况是“哦,我忘了关闭飞行模式”,转到设置,关闭它,并返回应用程序,此时,如果尚未成功或者已经过了一定的时间(例如24小时),它应自动重试。
就您的特定问题的详细信息而言,您应该向我们展示didFailWithError
报告的内容。如果您仍然遇到问题,我还建议您在请求之前检查postData
和postLength
,并确保它们具有有效值。
顺便说一下,ctrahey是对的,你的didReceiveData
有问题。这个过程通常是:
在您首次创建NSMutableData
时(或在didReceiveResponse
中)创建NSURLConnection
;
在didReceiveData
中向其附加数据,但对此数据不执行任何操作(除非您正在执行某些基于流的操作,否则您不会这样做);
评估connectionDidFinishLoading
中的结果并采取行动;和
请确保按上述方式实施didFailWithError
。