【问题标题】:How to handle NSFetchedResultsController fetch errors?如何处理 NSFetchedResultsController 获取错误?
【发布时间】:2011-06-01 04:43:14
【问题描述】:

这是来自 Apple 示例代码:

if (![fetchedResultsController_ performFetch:&error]) {
     /*
      Replace this implementation with code to handle the error appropriately.
      ...
      If it is not possible to recover from the error, ...
      */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

我想知道是否真的有必要总是终止应用程序?你怎么能“用代码替换这个实现以适当地处理错误”?您将如何“从错误中恢复”?

任何建议都将不胜感激,费边

【问题讨论】:

  • abort() 电话是一种恐吓策略。
  • 无论如何,这取决于获取的结果控制器正在寻找什么。这意味着对于应用程序中的不同内容,您需要以不同的方式处理错误。您关于 究竟该做什么NSError 对象的问题仍然有效,所以 +1
  • 我倾向于在屏幕上显示 NSError 的本地化描述,以便用户可以向技术支持报告一些内容。
  • 我认为abort() 也是应用程序接受的禁忌,表示错误,空数组是我的偏好

标签: iphone objective-c ios nsfetchedresultscontroller nserror


【解决方案1】:

好吧,显然没有人有其他(更好的?)解决方案,所以这是我的方法:

在我的 AppController 中,我添加了一个实例变量 errorString 和这个方法:

- (void)presentCoreDataError:(NSError *)error
                    withText:(NSString *)text
{
    NSMutableString *localErrorString = [[NSMutableString alloc] init];

    [localErrorString appendFormat:@"Failed to %@: %@", text, [error localizedDescription]];

    NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
    if(detailedErrors != nil && [detailedErrors count] > 0) {
        for(NSError* detailedError in detailedErrors) {
            [localErrorString appendFormat:@"- Detail: %@", [detailedError userInfo]];
        }
    } else {
        [localErrorString appendFormat:@"- %@", [error userInfo]];
    }

    UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[NSString stringWithFormat:@"Failed to %@", text]
                                                     message:@"Please send a report to the developer."
                                                    delegate:self
                                           cancelButtonTitle:@"Cancel"
                                           otherButtonTitles:@"Send Report", nil] autorelease];
    [alert show];

    self.errorString = localErrorString;
    [localErrorString release];
}

如果轻按“发送报告”,UIAlertView 代表将显示带有errorStringMFMailComposeViewController 和酷信使字体:)。否则它会调用abort():

- (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {     // Send Report
        MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
        picker.mailComposeDelegate = self;
        NSArray *toRecipients = [NSArray arrayWithObject:@"first@example.com"];
        [picker setToRecipients:toRecipients];
        [picker setSubject:@"Error Report"];
        [picker setMessageBody:[NSString stringWithFormat:@"The application crashed with the following error:<br><br><FONT FACE=%@> %@ </FONT>", 
                                @"courier", errorString] 
                        isHTML:YES];

        [navigationController presentModalViewController:picker animated:YES];
        [picker release];
    } else {
        abort();
    }
}

MFMailComposeViewControllerDelegate 显示第二个UIAlertView,只有一个按钮(显然该按钮的索引为0,因此它将调用abort()):

- (void)mailComposeController:(MFMailComposeViewController *)controller
          didFinishWithResult:(MFMailComposeResult)result
                        error:(NSError *)error
{
    [navigationController dismissModalViewControllerAnimated:YES];

    NSMutableString *messageString = [[NSMutableString alloc] init];

    if (result == MFMailComposeResultSent) {
        [messageString appendFormat:@"Thanks! "];
    }

    [messageString appendFormat:@"The application has to quit now."];
    UIAlertView *abortAlert = [[[UIAlertView alloc] initWithTitle:nil
                                                          message:messageString
                                                         delegate:self
                                                cancelButtonTitle:@"OK"
                                                otherButtonTitles:nil] autorelease];

    [abortAlert show];

    [messageString release];
}

【讨论】:

  • 您在生产中使用过这个解决方案吗?另外,你有没有收到任何电子邮件?
  • 我在生产中使用过,收到了两封邮件。
  • @fabian789 多年后仍然有用,谢谢!在初始化MFMailComposeViewController 之前,您可能还想使用[MFMailComposeViewController canSendMail] 来确定设备是否配置为发送电子邮件(如果没有,则提供备用警报消息)。
  • 嘿@fabian789,我应该在这个if条件下调用上面的函数“if (![context save:&error]) {....}”对,所以这里我可以传递错误参数,但是我应该传递的这个文本参数是什么。
  • @Ranjit 无论您希望用户看到什么文字 :)
猜你喜欢
  • 2012-02-11
  • 2021-12-19
  • 2018-10-24
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多