实现一个通用的弱存储盒,它知道值何时变为零

时间:2015-03-06 13:35:05

标签: objective-c swift generics weak-references

在我发布this问题后不久,我就知道了如何实现一个通用的弱存储盒,当它所拥有的弱值被解除锁定时,它知道并发送一个事件。

这就是我的意思(一个不起作用的示例实现):

class WeakValue<T: AnyObject> {
    weak var value: T? {
        didSet { /* Send event here when value is changed __or becomes nil__ */ }
    }
}

这不起作用。出于某种原因,属性观察者在观察到弱变量时不会被触发,它变为零(缺少特征,任何人?)。

所以,这就是我的想法:

private class Watcher {
    weak var delegate: WeakValue<AnyObject>?
    init(delegate d: WeakValue<AnyObject>) { delegate = d }
    deinit { delegate?.watcherWillDisappear() }
}

public class WeakValue<T: AnyObject> {
    private let storage = NSMapTable.strongToWeakObjectsMapTable()

    public init() {}
    public init(value v: T?) { value = v; reloadValue() }
    public weak var value: T? { didSet { reloadValue() } }

    private func reloadValue() {
        storage.removeAllObjects()
        if let v = value { storage.setObject(v, forKey: Watcher(delegate: unsafeBitCast(self, WeakValue<AnyObject>.self))) }
    }

    private func watcherWillDisappear() {
        /* Event triggered here */
    }
}

我的想法是使用NSMapTable的功能对我有利。以下是它的工作原理:

  1. 设置值后,会将强键/弱值对添加到NSMapTable。关键是一个Watcher类,只有NSMapTable持有一个引用(这就是它必须强大的原因)。该值是要存储的实际值。
  2. 每当该值被解除锁定时,NSMapTable将从其存储中删除键/值对,这反过来会使Watcher类失效(设置为键,只有NSMapTable持有引用),当这样做时,警告WeakValue类。
  3. 我的问题有两个:

    1. 这似乎不起作用(我没有在Playground上对此进行测试,我在一个真实的项目中进行了测试):我向WeakValue提供的测试类被解除了,但{ {1}}未被调用。为什么它不起作用?
    2. 这不是很有效,对吗? (为我想要存储的每个弱值创建一个新的watcherWillDisappear,并且在deallocked时我需要一个警报)

0 个答案:

没有答案