didSet for weak reference 没有按预期工作
didSet for weak reference not working as expected
我有这个小 Swift 脚本,它使用了弱引用:
#!/usr/bin/env swift
class Thing
{
deinit
{
print("Thing object deallocated")
}
}
class WeakThing
{
weak var thing: Thing?
{
didSet
{
print("Set thing to \(thing)")
}
}
}
var thing = Thing()
let weakThing = WeakThing()
weakThing.thing = thing
thing = Thing()
print("weakThing's thing is \(weakThing.thing)")
这会打印:
Set thing to Optional(Test.Thing)
Thing object deallocated
weakThing's thing is nil
但是,我希望它打印:
Set thing to Optional(Test.Thing)
Set thing to nil
Thing object deallocated
weakThing's thing is nil
我做错了什么?我看到对象正在被释放,thing
变量的值正在改变,但我的 didSet
代码没有执行。
didSet
和 willSet
不会在弱引用由于 ARC 自动归零时被调用。
如果您手动将 属性 设置为 nil
,您会看到调用了 didSet
代码。
我知道这个问题很老了,但我偶然发现了另一个答案,实际上在这里解决了问题:
对于它的价值,这是我按照上面引用的答案所建议的观看 deinit 的实现。只要确保您没有在 onDeinit 闭包中创建任何保留循环!
private var key: UInt8 = 0
class WeakWatcher {
private var onDeinit: () -> ()
init(onDeinit: @escaping () -> ()) {
self.onDeinit = onDeinit
}
static func watch(_ obj: Any, onDeinit: @escaping () -> ()) {
watch(obj, key: &key, onDeinit: onDeinit)
}
static func watch(_ obj: Any, key: UnsafeRawPointer, onDeinit: @escaping () -> ()) {
objc_setAssociatedObject(obj, key, WeakWatcher(onDeinit: onDeinit), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
deinit {
self.onDeinit()
}
}
在初始化弱变量时这样调用它:
self.weakVar = obj
WeakWatcher.watch(obj, onDeinit: { /* do something */ })
我有这个小 Swift 脚本,它使用了弱引用:
#!/usr/bin/env swift
class Thing
{
deinit
{
print("Thing object deallocated")
}
}
class WeakThing
{
weak var thing: Thing?
{
didSet
{
print("Set thing to \(thing)")
}
}
}
var thing = Thing()
let weakThing = WeakThing()
weakThing.thing = thing
thing = Thing()
print("weakThing's thing is \(weakThing.thing)")
这会打印:
Set thing to Optional(Test.Thing)
Thing object deallocated
weakThing's thing is nil
但是,我希望它打印:
Set thing to Optional(Test.Thing)
Set thing to nil
Thing object deallocated
weakThing's thing is nil
我做错了什么?我看到对象正在被释放,thing
变量的值正在改变,但我的 didSet
代码没有执行。
didSet
和 willSet
不会在弱引用由于 ARC 自动归零时被调用。
如果您手动将 属性 设置为 nil
,您会看到调用了 didSet
代码。
我知道这个问题很老了,但我偶然发现了另一个答案,实际上在这里解决了问题:
对于它的价值,这是我按照上面引用的答案所建议的观看 deinit 的实现。只要确保您没有在 onDeinit 闭包中创建任何保留循环!
private var key: UInt8 = 0
class WeakWatcher {
private var onDeinit: () -> ()
init(onDeinit: @escaping () -> ()) {
self.onDeinit = onDeinit
}
static func watch(_ obj: Any, onDeinit: @escaping () -> ()) {
watch(obj, key: &key, onDeinit: onDeinit)
}
static func watch(_ obj: Any, key: UnsafeRawPointer, onDeinit: @escaping () -> ()) {
objc_setAssociatedObject(obj, key, WeakWatcher(onDeinit: onDeinit), objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
deinit {
self.onDeinit()
}
}
在初始化弱变量时这样调用它:
self.weakVar = obj
WeakWatcher.watch(obj, onDeinit: { /* do something */ })