防止数据竞争
Swift 的新参与者类型的一个核心优势是它们可以帮助我们防止所谓的“数据竞争”——即当两个单独的线程试图同时访问或改变同一数据时可能发生的内存损坏问题。
竞争条件仍然可能存在
然而,虽然我们的用户加载和存储代码现在可以保证不会出现低级数据竞争,但这并不意味着它一定不会出现竞争条件。虽然数据竞争本质上是内存损坏问题,但竞争条件是当多个操作以不可预测的顺序发生时发生的逻辑问题。 事实上,如果我们最终使用新的 UserLoader 同时在多个地方加载同一个用户,我们很可能会遇到竞争条件,因为最终会执行多个重复的网络调用。这是因为我们的 StoredUser 值只有在该用户完全加载后才会存在。
结论
因此,一般来说,当我们想要实现一种支持以非常安全的方式并发访问其底层状态的类型时,actor 是一种非常棒的工具。但是,同样重要的是要记住,将类型转换为 actor 将需要我们以异步方式与其交互,这通常会使此类调用的执行变得更加复杂(且更慢)——即使我们可以使用 async/await 等工具。
虽然在 Swift 的 actor 模式实现方面还有更多值得探索的地方(这绝对是我们将来会重新讨论的一个主题),以及使 Swift 代码线程安全的其他方法,但我希望本文能为您提供一些关于如何在您工作的代码库中使用 actors 的想法。