【发布时间】:2020-04-26 22:46:46
【问题描述】:
我从 WWDC 2016 离开时了解到,我们应该警惕直接从 Swift 使用基于 C 的 struct API。在Concurrent Programming With GCD in Swift 3 中,谈到基于 C 的锁,它们非常具体:
...在 Swift 中,由于您拥有整个 Darwin 模块,您实际上会看到基于
struct的传统 C 锁。但是,Swift 假设任何struct都可以移动,而这不适用于互斥体或锁。所以我们真的不鼓励你从 Swift 中使用这些类型的锁。 ......如果您想要一些...看起来像您在 C 中拥有的锁,那么您必须调用 Objective-C 并在 Objective-C 中引入一个基类,该基类将您的锁作为 ivar .
然后您将公开
lock和unlock方法,如果您还需要它,还可以公开tryLock,当您将此类子类化时,您将能够从Swift 调用。 ...@implementation LockableObject { os_unfair_lock _lock; } - (void)lock { os_unfair_lock_lock(&_lock); } - (void)unlock { os_unfair_lock_unlock(&_lock); } @end
但是,观看 WWDC 2019 Developing a Great Profiling Experience,我注意到作者直接从 Swift 使用 os_unfair_lock,没有这个 Objective-C 包装器,有效:
private var workItemsLock = os_unfair_lock()
func subWorkItem(...) {
...
os_unfair_lock_lock(&self.workItemsLock)
...
os_unfair_lock_unlock(&self.workItemsLock)
...
}
从经验上看,这种直接使用os_unfair_lock 似乎可行,但这并不意味着什么。尊重 2016 年 WWDC 视频中的警告,我避免直接从 Swift 使用 os_unfair_lock。
所以,问题是,他们在 2019 年的示例中使用此 API 是否(稍微)草率?还是 2016 年的视频在其声明中不正确?或者,自 Swift 3 以来,基于 C 的 struct 的处理方式发生了变化,现在使这种模式变得安全了吗?
【问题讨论】: