创建一个弱的 UnsafeMutableRawPointer
Create a Weak UnsafeMutableRawPointer
所以我正在尝试使用 CoreAudio 方法 AUGraphAddRenderNotify(...)
但我需要在通知块中创建此通知的 class 的引用。因为这是一个 C 函数,所以我不能简单地添加一个 [weak self] in
闭包捕获。查看 Documentation, the last parameter of this method is allowed to be an UnsafeMutableRawPointer
that will be passed in during the execution of the block as the first parameter. Following this suggestion,这是我的代码:
let selfPointer = Unmanaged.passUnretained(self).toOpaque()
AUGraphAddRenderNotify(graph, { (audioPlayerPointer, _, _, _, _, _) -> OSStatus in
let audioPlayer = Unmanaged<AudioPlayer>.fromOpaque(audioPlayerPointer).takeUnretainedValue()
...
return noErr
}, selfPointer)
这是我的问题:
我需要弄清楚如何安全地获取此指针背后的值(占 nil)。更具体地说,我想安全地访问 audioPlayer 并确保在我使用它时它没有被释放。目前,一切正常,直到 audioPlayer 被解除分配然后我的应用程序崩溃。我知道我可以使用 AUGraphRemoveRenderNotify(...)
在对象被释放之前停止通知,但不幸的是这种方法不是我正在寻找的。如何检查指针指向的对象是否已被释放?
提前致谢!
弱引用并不是那样工作的
有趣的是,弱引用实际上并不指向它们建模的目标对象。它们指向边 tables,其生命周期与目标对象不同。
- 当第一个对对象的弱引用被创建时,一个 side-table 条目被分配。
- 每个弱引用的创建都会增加 side-table 条目的引用计数,而每个弱引用的销毁都会减少它。
- 一旦目标对象被解除分配,side-table 条目将保留在原位。这样,所有的弱引用都不会变成悬挂指针。
- 在目标对象最终解除分配后,所有访问弱引用(现已失效)的尝试都会导致弱引用被
nil
淘汰(这就是您观察到的用户),但也减少了 side-table entry
- 因此,每个弱引用要么需要被销毁(例如超出范围),要么在侧 table 条目到期之前尝试被访问。
因为这些 table 条目没有暴露给 "user land" Swift 代码,你不能为它们创建一个原始指针,所以你不能真正处理以这种方式使用弱引用。
其他想法
虽然我还没有尝试过,但我对你可以做什么有一些想法。
您可以利用 UnsafeMutableRawPointer
指针传入 Weak<T>
包装器,例如:
struct Weak<T: AnyObject> {
wear var object: T?
}
虽然我认为在这种情况下它必须是 class
。
- 或其他一些机制,例如传入闭包(弱捕获对象)
所以我正在尝试使用 CoreAudio 方法 AUGraphAddRenderNotify(...)
但我需要在通知块中创建此通知的 class 的引用。因为这是一个 C 函数,所以我不能简单地添加一个 [weak self] in
闭包捕获。查看 Documentation, the last parameter of this method is allowed to be an UnsafeMutableRawPointer
that will be passed in during the execution of the block as the first parameter. Following this suggestion,这是我的代码:
let selfPointer = Unmanaged.passUnretained(self).toOpaque()
AUGraphAddRenderNotify(graph, { (audioPlayerPointer, _, _, _, _, _) -> OSStatus in
let audioPlayer = Unmanaged<AudioPlayer>.fromOpaque(audioPlayerPointer).takeUnretainedValue()
...
return noErr
}, selfPointer)
这是我的问题:
我需要弄清楚如何安全地获取此指针背后的值(占 nil)。更具体地说,我想安全地访问 audioPlayer 并确保在我使用它时它没有被释放。目前,一切正常,直到 audioPlayer 被解除分配然后我的应用程序崩溃。我知道我可以使用 AUGraphRemoveRenderNotify(...)
在对象被释放之前停止通知,但不幸的是这种方法不是我正在寻找的。如何检查指针指向的对象是否已被释放?
提前致谢!
弱引用并不是那样工作的
有趣的是,弱引用实际上并不指向它们建模的目标对象。它们指向边 tables,其生命周期与目标对象不同。
- 当第一个对对象的弱引用被创建时,一个 side-table 条目被分配。
- 每个弱引用的创建都会增加 side-table 条目的引用计数,而每个弱引用的销毁都会减少它。
- 一旦目标对象被解除分配,side-table 条目将保留在原位。这样,所有的弱引用都不会变成悬挂指针。
- 在目标对象最终解除分配后,所有访问弱引用(现已失效)的尝试都会导致弱引用被
nil
淘汰(这就是您观察到的用户),但也减少了 side-table entry - 因此,每个弱引用要么需要被销毁(例如超出范围),要么在侧 table 条目到期之前尝试被访问。
因为这些 table 条目没有暴露给 "user land" Swift 代码,你不能为它们创建一个原始指针,所以你不能真正处理以这种方式使用弱引用。
其他想法
虽然我还没有尝试过,但我对你可以做什么有一些想法。
您可以利用
UnsafeMutableRawPointer
指针传入Weak<T>
包装器,例如:struct Weak<T: AnyObject> { wear var object: T? }
虽然我认为在这种情况下它必须是 class
。
- 或其他一些机制,例如传入闭包(弱捕获对象)