0

我通过单击按钮调用服务器,连接didReceiveData返回 aNull并使应用程序崩溃。但是有一个条件来检查数据是否是if,在条件下再次启动服务器调用是执行此操作的最佳实践吗?elseNullif

-(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];

}
4

2 回答 2

0

在回答您关于是否应在失败时立即重新发起请求是一种好习惯的问题时,答案是否定的。如果您确实想重试,您应该:

  • 只有在另一个请求有合理的成功机会时才这样做(例如,它没有因为完全缺乏网络连接而失败;只有在您的Reachability类的实现告诉您网络连接已重新建立时,您才重试);

  • 采用“最大重试次数”逻辑来确保将重试次数限制在某个合理的范围内(例如,您不想用完用户的数据计划、担心设备性能、用户体验等);

  • 在重试之前延迟一些时间(例如,如果您的服务器因为请求不堪重负而没有响应,那么用源源不断的请求流来打击它也无济于事);和

  • 如果连接失败并且用户将应用程序返回到前台,则重新开始该过程(例如,常见情况是“哦,我忘记关闭飞行模式”,转到设置,将其关闭,然后返回应用程序,在哪一点,如果它还没有成功或者如果它已经过去了一定的时间(例如24小时),它应该自动重试。

就您的特定问题的细节而言,您应该向我们展示didFailWithError报告的内容。如果您仍然遇到问题,我还建议您在请求之前检查postDatapostLength确保它们具有有效值。

顺便说一句,ctrahey 是正确的,您的didReceiveData. 流程一般是:

  • NSMutableData当你第一次创建NSURLConnection(或)时创建一个didReceiveResponse

  • 将数据附加到它didReceiveData,但对这些数据不做任何事情(除非你正在做一些基于流的操作,你不是);

  • 评估结果并采取行动connectionDidFinishLoading;和

  • 确保您didFailWithError按照上面讨论的方式实施。

于 2013-02-17T18:03:41.857 回答
0

receivedData 需要是一个实例变量,以便它具有在对委托方法的调用之间持续存在的存储持续时间。一种常见的模式是在它的 getter 中使用惰性实例化(使其成为“私有” @property)。

你现在拥有它的方式,如果你得到一个以上的块,你正在清除以前的块(实际上并没有让其他任何东西访问你的数据)。

我只能假设您正在适当地实现其他委托方法......

于 2013-02-17T17:14:38.900 回答