有什么方法可以检测到“ UnsafeMutablePointer”吗?

时间:2020-01-08 13:21:41

标签: ios swift

我有一个自定义的观察者,它正在检查观察对象是否已更改。该对象在UnsafeMutablePointer中保留对原始属性(指针)的引用...问题是所有工作都很好,除非原始值被释放,并且我开始从现在占用那部分内存的位置开始获取随机值。 。 有什么方法可以检测到原始对象不见了,以便使观察者无效?

编辑:为了清楚说明我要实现的目标,我添加了当前的实现(对本地类变量有效):

class Observer<Observed> where Observed: Equatable {

    typealias Binder = ((Observed) -> ())
    typealias Storage = UnsafeMutablePointer<Observed>

    private var storage: Storage

    private var bind: Binder

    private var running: Bool

    init(_ value: Storage, binder: @escaping Binder) {
        storage = value
        bind = binder
        running = true

        var val: Observed = value.pointee
        DispatchQueue.global().async {
            while self.running {
                if val != value.pointee {
                    self.bind(value.pointee)
                    val = value.pointee
                }
            }
        }
    }

    var value: Observed {
        return storage.pointee
    }

    deinit {
        running = false
    }

}

1 个答案:

答案 0 :(得分:2)

否;您有责任确保不安全的指针不会超过其引用的对象。 (“重要的内存详细信息是您的问题,这是Swift通常用”不安全”表示的意思。)

通常正确的工具是weak引用而不是指针。


您的观察代码在许多方面都不正确。紧密循环读取值并将其与现有值进行比较的基本方法是,即使没有其他问题,也将非常耗电。这也是无效的,因为您的指针不是线程安全的。您无法在随机线程上读取它,并且无法保证它具有一致的值。

Swift不能保证值类型在内存中位于相同的位置,因此即使值仍然“存在”,也不能保证您的指针指向它。它甚至不保证值类型具有堆(即持久性)内存位置;它们可以存储在堆栈中,甚至可以存储在寄存器中。当您使用指向它的指针时,它可能会创建一个临时副本以提供一个内存位置,但不能保证它与其他对其引用的内存相同。这就是值类型的重点。它可以自由复制和移动(在某些情况下甚至可以完全优化)。如果需要能够引用到实例,则需要引用类型。