ios - 当弱引用对象(任意类型)被释放时,我可以 Hook 吗?

标签 ios swift dictionary weak-references

我正在用 Swift 编写一个容器类,其工作方式类似于 Java 中的 java.util.WeakHashMap。我当前的实现在这里。

class WeakRefMap<Key: Hashable, Value: AnyObject> {

    private var mapping = [Key: WeakBox<Value>]()

    subscript(key: Key) -> Value? {
        get { return mapping[key]?.raw }
        set {
            if let o = newValue {
                mapping[key] = WeakBox(o)
            }
            else {
                mapping.removeValueForKey(key)
            }
        }
    }

    var count: Int { return mapping.count }
}

class WeakBox<E: AnyObject> {
    weak var raw: E!
    init(  _ raw: E) { self.raw = raw }
}

在此实现中,容器中保存的对象通过 WeakBox 进行弱引用,因此保存值永远不会阻止对象在不再需要时被释放。

但是这段代码显然有问题;即使条目的对象被释放,条目仍然保留。

为了解决这个问题,我需要在释放所持有的对象之前进行 Hook ,并删除其(相应的)条目。我知道仅适用于 NSObject 的解决方案,但它不适用于 AnyObject

有人可以帮助我吗?谢谢。 (^_^)

最佳答案

遗憾的是,当 weak var raw 属性值被释放时,didSetwillSet 观察者不会被调用。

因此,在这种情况下,您必须使用 objc_setAssociatedObject:

// helper class to notify deallocation
class DeallocWatcher {
    let notify:()->Void
    init(_ notify:()->Void) { self.notify = notify }
    deinit { notify() }
}

class WeakRefMap<Key: Hashable, Value: AnyObject> {

    private var mapping = [Key: WeakBox<Value>]()

    subscript(key: Key) -> Value? {
        get { return mapping[key]?.raw }
        set {
            if let o = newValue {
                // Add helper to associated objects.
                // When `o` is deallocated, `watcher` is also deallocated.
                // So, `watcher.deinit()` will get called.
                let watcher = DeallocWatcher { [unowned self] in self.mapping[key] = nil }
                objc_setAssociatedObject(o, unsafeAddressOf(self), watcher, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
                mapping[key] = WeakBox(o)
            }
            else {
                mapping[key] = nil
            }
        }
    }

    var count: Int { return mapping.count }

    deinit {
        // cleanup
        for e in self.mapping.values {
            objc_setAssociatedObject(e.raw, unsafeAddressOf(self), nil, 0)
        }
    }
}

注意:Swift 1.2 之前。此解决方案不适用于任意 Swift 类。

关于ios - 当弱引用对象(任意类型)被释放时,我可以 Hook 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28670796/

相关文章:

ios - 使用未声明的类型 'FIRMessagingDelegate'

python - "OrderedDict()"使用 OrderedDict() 时自身打印

ios - MKAnnotationView 层不是预期的类型 : MKLayer

IOS Swift,如何检测文件上传点击UIWebView内部打开照片上传对话框

xcode - 在 Swift 中添加手势和动画

json - Alamofire 请求慢?

scala - 将列表转换为映射,其中键为 Scala 中的索引

java - 如何在单个语句中创建具有映射的映射

ios - 以编程方式启动没有方向或地点标记的 Apple map

ios - uikeyboardwillhidenotification 滚动时调用方法两次