【问题标题】:Proper way for handling Core Data save error处理核心数据保存错误的正确方法
【发布时间】:2014-04-18 04:10:43
【问题描述】:

在我的应用中,由于这个核心数据保存错误处理代码,我收到了一堆 SIGABRT 崩溃报告(来自特定用户):

NSError *error = nil;
if (![moc save:&error])
{
    if(error)
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
}

有没有比使用 abort() 终止进程更好的方法来处理核心数据保存错误?

【问题讨论】:

标签: ios objective-c core-data


【解决方案1】:

所以 Core Data 实际上为您提供了很多关于为什么它无法保存或为什么验证失败的信息。您可以提取该信息并以有用的方式将其呈现给用户,然后让他/她修复它(如果我们谈论的是用户生成的数据)。这是我想出的解决方案:iPhone Core Data "Production" Error Handling

【讨论】:

  • 这是一个有用的代码sn-p!下一步是将错误消息与 UI 中的输入字段相关联,在其下方放置一个红色感叹号,当用户点击它时,会弹出一个漂亮的表格,其中包含有关错误的详细信息;)
  • @CouchDeveloper 那真是太棒了!然后我们会有 Ruby on Rails 行为 :) 这听起来像是一个非常有用的开源项目的想法!
  • 同样的想法,在这里... ;)
【解决方案2】:

基于 save 错误不应出现在生产中的事实,我最好的建议是遵循类似的模式。

NSError *error = nil;
if ([self.managedObjectContext save:&error] == NO) {
    NSAssert(NO, @"Save should not fail");
    [self showAlert];
}

- (void)showAlert {
    UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Could Not Save Data"
                                                        message:@"There was a problem saving your data but it is not your fault. If you restart the app, you can try again. Please contact support (support@domain.com) to notify us of this issue."
                                                       delegate:self
                                              cancelButtonTitle:@"Ok"
                                              otherButtonTitles:nil];
    [alertView show];
}

- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
    abort();
}

感谢NSManagedObjectContext save error 中所述的Matthew Morey

我真的很喜欢这种方法,因为它会通知用户发生了不好的事情。 除此之外,我还将创建一个可以通过电子邮件发送给支持人员的日志文件。在日志中,您将尽可能多地提供信息以调查错误。例如,要实现这一点,您可以使用CocoaLumberjack。还可以查看 NSSCreenCast 的 Mailing Logs

【讨论】:

  • 我能以某种方式完全避免 abort() 的事情吗?
  • 我不同意保存不应在生产中失败。如果对象未通过验证或违反参照完整性规则,则保存可能会失败。不能总是在 UI 代码中实现对象验证。向用户显示出了问题然后中止并不能真正帮助用户。根据具体情况,程序应该将上下文回滚到一个逻辑正确状态,然后重放导致这个错误的动作,假设这最终可以成功,或者将被用户取消。
  • @CouchDeveloper 我认为 Marcus Zarra 会对此感到失望。 ;) 我通常不在 Core Data 中使用验证。仅在应用程序级别。更容易维护。
  • ...等待@MarcusS.Zarra 提示。
  • 除了显示警报之外,它不仅仅是中止应用程序。我还建议登录到文件...
【解决方案3】:

使用此代码确保它会对您有所帮助

- (void)saveContext
{
    NSError *error = nil;
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            abort();
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多