我想在 Realm 写入失败并引发错误时捕获错误。
我运行了一个测试,尝试使用相同的primaryKey(id)保存两个对象。 Realm 限制RLMException,但未捕获。
static func save(article: Article) -> Bool {
do {
let realm = try Realm()
try realm.write {
realm.add(article)
}
return true
} catch {
print("***** ERROR *******")
return false
}
}
我进行如下测试。
func testDuplicateSave() {
let id = 7777
let a = Article()
a.id = id
RealmClient.save(a)
let a2 = Article()
a2.id = id
let resut = RealmClient.save(a2)
XCTAssertFalse( resut )
}
最佳答案
如果尝试使用已经存在的主键持久化对象,则Realm确实会引发Objective-C异常。
Swift的错误处理无法捕获Objective-C异常。它基于ErrorType
返回机制,该机制“翻译”了Objective-C中基于NSError
指针的API。
通常应该避免在Objective-C中抛出和捕获异常,因为它代价更高。与许多其他语言不同,它仅应在无法预见的真正特殊情况下执行,而不是在尝试执行可预见的失败操作(例如在NSFileManager
的I/O磁盘操作上可以看到。
那么,为何Realm抛出异常而不是在该位置失败?
我们认为用一个已经存在的主键持久化一个对象是程序员的错误。您可以轻松地检查自己是否已经存在主键。出于这个原因,我们将其留给开发人员负责,以避免混淆各种错误的根本原因。
static func save(article: Article) -> Bool {
// Opening a Realm fails if the file is inaccessible on the file
// system, it has a different schema version, it is encrypted
// and you don't provide matching credentials or the virtual
// address space is exhausted. If you don't provide explicit
// error handling for any of this cases at this place, then
// you can open the Realm by a force-try without hesitation.
let realm = try! Realm()
// Write transactions are mutually exclusive. So starting the
// transaction before checking whether an object with the same
// primary key already exists, ensures that such an object
// can't be concurrently created by any other thread.
realm.beginWrite()
if let _ = realm.objectForPrimaryKey(Article, article.id) {
// Object exists already.
realm.cancelWrite()
return false;
}
realm.add(article)
// Write transactions fail if it would cause the file to
// outgrow the virtual address space or the disk capacity.
// If you don't provide explicit error handling for this case
// at this place, then you can commit the write transaction
// by a force-try without hesitation.
try! realm.commitWrite()
return true
}
关于swift - 使用重复的primaryKey保存到Realm时未捕获错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38369370/