我以前习惯使用SQL数据库,我是Realm的新手,到目前为止,我对这款新移动数据库的易用性印象深刻。 但有一点我真的不明白:如何处理错误抛出?
举个简单的例子:
我想在Realm DB中存储一些市场股票
每只股票都有一个"符号"作为唯一标识符:APPL for Apple Inc,TSLA for Tesla Motors Inc等
我认为将这些符号声明为主键是有意义的,因为它不可能在数据库中多次使用相同的符号
当用户单击符号(符号列表中)时,此符号将保存在db。
在此Raywenderlich tutorial中,有人说:"为了简化本教程中所需的代码,您将尝试使用!调用抛出错误的Realm方法时。在你自己的代码中,你应该使用try和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'.'
问题是在运行时没有捕获到这个错误:我发生了崩溃。
我的问题不是如何避免这种崩溃,我当然理解通过在数据库中写入任何内容之前进行简单的测试来避免它很容易:)< / p>
我的问题是我们如何在Realm中捕捉潜在的写作错误?
我做错了吗?
答案 0 :(得分:8)
do/try/catch
捕获Swift错误,这与Objective-C异常完全不同。 Realm遵循Foundation的错误报告模式:API误用错误抛出不打算捕获的异常(并且不能在Swift中捕获),并且可恢复的错误抛出Swift错误(或使用{{1在Objective-C中输出参数。
添加具有重复主键的对象被视为API滥用,因此这是一个致命错误,因为“处理”它的路由是修复代码中的错误。在尝试保存新数据时,可生成由NSError
捕获的Swift错误的可恢复错误示例正在耗尽磁盘空间。
答案 1 :(得分:3)
有两种不同类型的错误:程序员错误和预期错误。 Realm以不同的方式处理这两种类型的错误。
程序员错误包括诸如从不正确的线程访问对象,越界集合访问,尝试插入具有重复主键的对象等情况。 Realm通过抛出Objective-C异常来响应这些程序员错误。这些例外不是为了捕获和处理,因为它们表明了Realm用户代码中的错误。
预期错误包括文件不存在,权限错误,写入磁盘失败等问题。由于程序控制之外的因素,即使使用正确编写的代码,也会发生这些事情。这些内容为NSError
,可以使用do
/ try
/ catch
从Swift中捕获。请注意,Realm的Objective-C API有一些不会暴露NSError
的便捷方法。在这些情况下,预期的错误将引发异常,因为Realm没有其他途径来传达故障。您应该使用返回NSError
的API变体,而不是尝试捕获和处理这些便捷方法引发的异常。
答案 2 :(得分:0)
嗨,错误行说“现有价值”,难道你不尝试用'APPL'多次写同一个主键吗? 你需要更新它,而不是覆盖。
如果你试图再次“添加”相同的值,它就会阻止你。
(抱歉英文不好x))