realm.write和realm.beginWrite+realm.commitWrite有什么区别?

17

在Realm中,执行写事务有两种方式,它们之间有什么区别?

1.

try! realm.write {
  ...
}

2.

realm.beginWrite()
...
try! realm.commitWrite()
2个回答

14

更新于2017年4月19日,更加简洁明了,并解释了选择某个方法的优势。


从功能上来说,这两种方法没有区别。方法realm.write是一种更方便的写入事务方法,但在内部,它仍然只是使用相同的beginWrite/commitWrite事务API:

public func write(_ block: (() throws -> Void)) throws {
    beginWrite()
    do {
        try block()
    } catch let error {
        if isInWriteTransaction { cancelWrite() }
        throw error
    }
    if isInWriteTransaction { try commitWrite() }
}

虽然realm.write {}的写法更简洁快捷,但还是有一些情况你可能需要使用beginWrite/commitWritebeginWritecommitWrite()更加手动化,这在你需要更多控制时非常好。realm.write {}实现了自己的错误处理程序,但如果你想要执行自己特定的错误处理,你可以使用beginWrite/commitWrite(或者你也可以尝试将try realm.write {}放入自己的do/catch块中)。另一个控制力更大的优点是你可以使用cancelWrite()来取消一个已经开始的事务,具体取决于你希望控制处理特定写事务的程度以及如何组织代码。视你计划执行的写事务的复杂性而定,两者都可以轻松考虑。realm.write {}使用闭包,使得事务代码的包装非常优雅、简洁,但你可能会失去你想要的控制量。使用beginWrite/commitWrite可以获得更多控制,但最终需要用户在处理潜在错误方面做更多工作。实际上,realm.write只是使用beginWrite/commitWrite的更方便方法,两者几乎没有区别。你可以查看Realm Swift的源代码进行确认。
public func write(_ block: (() throws -> Void)) throws {
    beginWrite()
    do {
        try block()
    } catch let error {
        if isInWriteTransaction { cancelWrite() }
        throw error
    }
    if isInWriteTransaction { try commitWrite() }
}

因此,在使用这两种方法时没有任何区别。这两种方法都可供您选择,因此您可以选择最容易集成到您的代码中的那个。 :)

我可能有点近视,但我也看到了在 try! realm.write { 的情况下自动事务取消以防错误。 - EpicPandaForce
1
希望不是这样! :) 是的,realm.write 有一些额外的好处。使用 realm.beginWrite / realm.commitWrite 可以给您最终的手动控制,但这意味着您也需要负责自己的错误处理。(尽管如果您无论如何都使用 try! 关键字忽略错误处理,则所有这些都是无意义的)。 - TiM
我之前遇到过写事务在出错时没有被取消的奇怪情况,因此我认为 realm.write 在这方面更安全,就像 Realm-Java 中的 realm.executeTransaction() 一样。 - EpicPandaForce
@TiM,也许你应该在回答正文中添加有关细节方面的评论,这正是我的问题所在。 :) 谢谢! - Victor Laerte
@VictorLaerte 好想法!我会在我的回答中加入我们在这里讨论的内容。 :) - TiM

2
另一种使用 beginWritecommitWrite 的情况是当您不想触发更改通知时。为此,您可以将通知令牌传递给 commitWrite,如下所示:commitWrite(withoutNotifying: [token])
更多详细信息请参见 Realm 官方文章- 接口驱动写入

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接