【问题标题】:How to handle error with Realm during writing?如何在编写过程中处理 Realm 的错误?
【发布时间】:2016-06-28 10:32:52
【问题描述】:

我习惯使用 SQL 数据库,我是 Realm 的新手,到目前为止,我对这个新的移动数据库的易用性印象深刻。 但是有一点我真的不明白:如何处理错误抛出?

举个简单的例子:

我想在 Realm DB 中存储一些市场股票。
每只股票都有一个“符号”作为唯一标识符:APPL 代表 Apple Inc,TSLA 代表 Tesla Motors Inc 等。
我相信将这些符号声明为主键是有意义的,因为数据库中不可能有多次相同的符号
当用户点击一个符号(在符号列表中)时,该符号将保存在 db 中。

在这个Raywenderlich tutorial 中说:“为了简化本教程中所需的代码,你将使用 try! 来调用抛出错误的 Realm 方法。在你自己的代码中,你应该真的正在使用 try and do / catch 来捕获错误并适当地处理它们。”

所以按照下面的模式:

do {
    try realm.write {
        realm.add(symbol)
    }
}
catch let error as NSError {
    print("Something went wrong: \(error.localizedDescription)")
}

到目前为止,这是有道理的。
如果用户单击数据库中已经存在的符号,我会(非常合乎逻辑地)得到一个错误:

*** Terminating app due to uncaught exception 'RLMException', reason: 'Can't set primary key property 'symbol' to existing value 'APPL'.'

问题是在运行时没有捕获到这个错误:我已经崩溃了。

我的问题不是关于如何避免这种崩溃,我当然明白,在数据库中写入任何内容之前进行简单的测试很容易避免它:)

我的问题是我们如何在 Realm 中捕捉潜在的书写错误?
我做错了吗?

【问题讨论】:

    标签: swift swift2 realm


    【解决方案1】:

    do/try/catch 在 Swift 中捕获 Swift 错误,这与 Objective-C 异常完全不同。 Realm 遵循 Foundation 的错误报告模式:API 误用错误抛出不打算被捕获的异常(并且 不能在 Swift 中被捕获),可恢复的错误抛出 Swift 错误(或使用 NSError在 Objective-C 中输出参数)。

    添加具有重复主键的对象被视为 API 滥用,因此这是一个致命错误,因为“处理”它是为了修复代码中的错误。在尝试保存新数据时,会产生 Swift 错误并被catch 捕获的可恢复错误示例是磁盘空间不足。

    【讨论】:

    • 好的,感谢您非常准确的回答。无法捕捉错误以处理它们对我来说似乎很奇怪,但我确实理解它背后的哲学。最后我假设,与 Raywenderlich 教程中所说的相反,Realm 对使用“do/try/catch”语法冗长代码没有太大兴趣。应该坚持简单的“尝试!”语法...(除了磁盘空间不足类型的错误)
    • 感谢您的好回答。在我看来,从领域的角度来看,这非常糟糕
    【解决方案2】:

    有两种不同类型的错误:程序员错误和预期错误。 Realm 以不同的方式处理这两种类型的错误。

    程序员错误包括从不正确的线程访问对象、越界集合访问、尝试插入具有重复主键的对象等情况。 Realm 通过抛出一个 Objective-C 异常来响应这些程序员错误。这些异常并不打算被捕获和处理,因为它们表示 Realm 用户代码中的错误。

    预期错误包括文件不存在、权限错误、写入磁盘失败等内容。由于程序控制之外的因素,即使使用正确编写的代码也可能发生这些事情。这些暴露为NSErrors,可以使用do/try/catch从Swift中捕获。请注意,Realm 的 Objective-C API 有一些不公开NSError 的便捷方法。在这些情况下,预期的错误将引发异常,因为 Realm 没有其他途径来传达故障。与其尝试捕获和处理这些便捷方法引发的异常,不如使用返回 NSError 的 API 变体。

    【讨论】:

    • 感谢@bdash 补充信息。我没有足够的“声誉”来做 +1,但如果可以的话,我会做的......
    【解决方案3】:

    您好,错误行说“到现有值”,您不尝试使用 'APPL' 多次写入相同的主键吗? 你需要更新它,而不是覆盖。

    如果您尝试再次“添加”相同的值,它会阻止您。

    (抱歉英语不好 x))

    【讨论】:

    • 感谢您的回答。您完全同意:错误是由于我试图添加一个已经在 db 中的对象(具有相同的主键)。错误的原因对我来说很清楚,但我不明白我如何在运行时捕获错误而不是崩溃?
    • 如果这些东西可以帮助你? realm.io/docs/swift/latest/…
    • 在这种特殊情况下肯定会有所帮助,但这只是一个例子。我的问题更笼统,是关于在写入操作期间捕获错误:我们该怎么做?
    • 真的在进行中,我认为这不是一个好主意,因为您不会开车杀死路上所有的人,然后再看到结果。您需要先检查是否有人在您面前。我想这和这里的想法是一样的。做这个 -> var tanDogs = realm.objects(Dog.self).filter("yourKey = 'whatYouExpect'") 并寻找结果,如果它是 nil,你会显示一个消息错误,一切都好,我想让我发布跨度>
    • 谢谢奥列格。我们同意必须做些什么来避免这种崩溃(正如我的问题中的预期所引起的:在数据库中写入任何内容之前只做一个简单的测试)。但问题是关于“捕捉错误”,正如 Raywenderlich 教程中所建议的那样。这是否意味着没有办法在 Realm 中捕获错误?但在这种情况下,为什么 Raywenderlich 会推荐它呢?
    猜你喜欢
    • 2012-04-17
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-18
    • 1970-01-01
    • 2012-03-23
    相关资源
    最近更新 更多