就像问题所示,我试图在用户向服务器发送一些数据后不冻结用户界面。就我而言,他们可能会发送大量数据和服务器端,我必须为多个查询做一个foreach循环。
虽然所有这一切都在发生,但我并不希望用户等待回复,所以我会在"发送"之后解雇模式VC。点击。数据仍会插入到数据库中,但如果出现错误怎么办?现在我在模态VC被解除后显示UIAlertView但是我得到了错误的访问错误。什么是显示错误的最佳方式?
- (void)send:(id)sender{
if ([[Data sharedInstance].someData objectForKey:@"time"] != NULL) {
[self dismissViewControllerAnimated:YES completion:^(){
NSMutableDictionary *paramDic = [NSMutableDictionary new];
[paramDic setValue:[[Data sharedInstance].someData objectForKey:@"oneArray"] forKeyPath:@"oneArray"];
[paramDic setValue:[NSArray arrayWithObjects:[[[Data sharedInstance].someData objectForKey:@"two"] valueForKey:@"Name"], [[[Data sharedInstance].someData objectForKey:@"two"] valueForKey:@"State"], [[[Data sharedInstance].someData objectForKey:@"two"] valueForKey:@"Country"], nil] forKeyPath:@"twoArray"];
[paramDic setValue:[[[Data sharedInstance].someData objectForKey:@"three"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKeyPath:@"three"];
[paramDic setValue:[[NSUserDefaults standardUserDefaults] valueForKey:@"username"] forKey:@"username"];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:paramDic options:NSJSONWritingPrettyPrinted error:nil];
NSURL *url = [NSURL URLWithString:@"http://localhost/myapp/handleData.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
NSString *length = [NSString stringWithFormat:@"%d", jsonData.length];
[request setValue:length forHTTPHeaderField:@"Content-Length"];
[request setValue:@"json" forHTTPHeaderField:@"Data-Type"];
[request setHTTPBody:jsonData];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (![httpResponse statusCode] == 200 || ![[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] isEqualToString:@"success"]) {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Problem on the server. Please try again later." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
}];
}];
}
我现在是怎么做的......什么是更好的方式?
答案 0 :(得分:1)
我认为这个问题与你的嵌套完成块有关。因为您将Web服务调用放在模态解雇完成块中,所以当它完成并开始执行URL完成块时,负责该块的类/控制器已经被忘记/销毁/解除分配/无论如何。至少,在您尝试显示警报视图时,视图不再存在。您已将self
列为该警报视图的代理,但self
不再存在。
首先尝试这一点:而不是尝试在后台线程中的不再内存视图中显示警报(即使视图仍然存在,也是大禁忌),尝试向主线程发布通知您可以在应用程序的其他位置(例如根视图控制器)中选择并从那里显示警报:
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
if (![httpResponse statusCode] == 200 || ![[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding] isEqualToString:@"success"]) {
dispatch_async(dispatch_get_main_queue(),^{
// observe this notification in root view controller or somewhere
// that you know will be in memory when it fires
[[NSNotificationCenter defaultCenter] postNotificationName:@"ErrorAlert"
object:nil
userInfo:imageDict];
});
}
}];
如果由于应用在视图被解除时丢弃了您的完成块仍然无效,您将需要创建一个单独的类,负责发送此Web服务请求而不是直接在完成块。但是,请记住在主线程上显示警报:)
答案 1 :(得分:1)
上述答案很有价值。但我认为这是导致问题的原因。
变化:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Problem on the server. Please try again later." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
要:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@"Error" message:@"Problem on the server. Please try again later." delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
希望这有帮助。