swift - 使用重复的primaryKey保存到Realm时未捕获错误

标签 swift error-handling realm

我想在 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/

相关文章:

ios - AVPlayer 的奇怪行为

ios - 了解 AlamoFire OAuth 示例

javascript - 为什么我的 ExpressJS 错误处理程序不起作用?

php - 即使禁用 VERIFYPEER、VERIFYHOST 也会出现 SSL 连接错误

android - 从 Realm 检索列表后填充 RecyclerView 的最佳模式是什么?

android - Realm 单元测试

ios - 约束问题

ios - 在交互式 UI 上保存 Realm 对象

python-3.x - Jsonify 异常错误

Android Realm 查询不同的外键