模态解雇后显示错误消息

时间:2014-06-20 14:15:47

标签: ios objective-c error-handling nsurlconnection

就像问题所示,我试图在用户向服务器发送一些数据后不冻结用户界面。就我而言,他们可能会发送大量数据和服务器端,我必须为多个查询做一个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];
            }
        }];
    }];
}

我现在是怎么做的......什么是更好的方式?

2 个答案:

答案 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];

希望这有帮助。