我试图弄清楚为什么即使在对象保持存在之后,弱引用也会丢失其引用对象。
我的代码如下:
MyClass {
deinit {
print("I'm being deinited") // This never gets called
}
func doConnection(connection: Future<Data, ServerConnectionError>) {
Future<Void, ServerConnectionError> { complete in
connection.onSuccess {[weak self] data in
guard let strongSelf = self else {
return // This line gets called
}
...
}
}
}
}
通过检查内存图,我可以看到在未来完成之前self引用的对象仍然存在(通过内存地址判断)。
在找到它的弱引用为nil(最右边的MyClass实例)后,所谓缺失对象的内存图形如下所示:
上部子树是应该保持对象活着的子树,而下部子树与当前的堆栈执行有关。第3级(从右到左)中许多其他人引用的对象(蓝色框)包含对数组的强引用,该数组又保存对MyClass实例的引用。
编辑:问题在以下答案中得到解决。冷却过后将标记为已解决。
答案 0 :(得分:0)
将包含self
的任何捕获列表移动到最外面的闭包,否则它可能会创建一个参考周期:
MyClass {
deinit {
print("I'm being deinited") // This never gets called
}
doConnection(connection: Future<Data, ServerConnectionError>) { [weak self] in
Future<Void, ServerConnectionError> { complete in
connection.onSuccess { data in
guard let strongSelf = self else {
return // This line gets called
}
...
}
}
}
}
答案 1 :(得分:0)
默认情况下,闭包表达式通过对这些值的强引用来捕获其周围作用域的属性。但是你在自我封闭/承诺中将自己定义为弱者。您可以删除[weak self]
使用[unowned self]
或将闭包列表移动到外部块。只要你的MyClass实例在履行承诺时没有被释放。仅当内存压力触发垃圾回收时,才会释放没有强引用的对象。但是,在ARC中,只要删除最后一个强引用,就会释放值。通过在闭包中使自己弱,当允许ARC没有其他强引用时,允许ARC删除对MyClass实例的引用,在取消初始化MyClass实例后,将删除弱引用。
答案 2 :(得分:0)
问题解决了。好的,所以我不知道发生了什么,但是经过多次尝试调试后它自行修复了。还有一件事仍然是错误的是调试器在闭包内显示self
为nil
(这在调试过程中增加了很长时间),但是guard let
块执行成功并且我得到了强烈引用该对象。