gpt4 book ai didi

我们可以直接从 Swift 使用基于 C 结构的 API 吗?

转载 作者:行者123 更新时间:2023-12-04 10:08:34 37 4
gpt4 key购买 nike

我离开 WWDC 2016 时了解到我们应该警惕直接从 Swift 中使用基于 C 的 struct API。在 Concurrent Programming With GCD in Swift 3 ,谈到基于 C 的锁,它们非常具体:

... And in Swift, since you have the entire Darwin module at your disposition, you will actually see the struct based traditional C locks. However, Swift assumes that anything that is struct can be moved, and that doesn't work with a mutex or with a lock. So we really discourage you from using these kind of locks from Swift. ...

... And if you want something ... that looks like the locks that you have in C, then you have to call into Objective-C and introduce a base class in Objective-C that has your lock as an ivar.

And then you will expose lock and unlock methods, and a tryLock if you need it as well, that you will be able to call from Swift when you will subclass this class. ...

@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 的处理是否发生了变化,现在使这种模式安全?

最佳答案

使用 private var workItemsLock = os_unfair_lock() 的 API 示例可能会在运行时失败。

来自 C 的线程原语需要一个稳定的内存位置,因此要使用它们或将这些原语之一直接作为其成员的其他结构,您必须使用 UnsafePointer。这样做的原因是 UnsafePointer API 一旦分配了一 block 内存,该内存就稳定了,无法移动或被编译器轻易复制。

如果您像这样更改示例,它现在有效

private var workItemsLock: UnsafeMutablePointer<os_unfair_lock> = {
// Note, somewhere else this will need to be deallocated
var pointer = UnsafeMutablePointer<os_unfair_lock>.allocate(capacity: 1)
pointer.initialize(to: os_unfair_lock())
return pointer
}()

func subWorkItem(...) {
...
os_unfair_lock_lock(self.workItemsLock)
...
os_unfair_lock_unlock(self.workItemsLock)
...
}

关于我们可以直接从 Swift 使用基于 C 结构的 API 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61449111/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com