我已经定义了一个名为Person
的类。这是我的代码:
class Person {
var closure: (() -> ())?
var name: String
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
然后我在名为Person
的课程中使用ViewController
:
class ViewController: UIViewController {
var person = Person(name: "john")
let aStr = "john is a cute boy"
override func viewDidLoad() {
super.viewDidLoad()
person.closure = {
print("\(self.aStr)")
}
person.closure!()
}
}
在我看来,关于我的代码的内存图片如下:
所以,从上面的图片来看,在我看来,它会在三个实例之间产生强大的参考周期,但我无法从Instruments
得到任何泄漏,所以我有些困惑。
此代码是否会导致强引用周期?
如果没有,ARC什么时候会取消分配Person
的实例? <{1}}类中名为deinit
的方法永远不会被调用。
答案 0 :(得分:2)
是的,这是一个典型的保留周期。
要解决此问题,请在闭包中使用[weak self]
person.closure = { [weak self] in
guard let strongSelf = self else { return }
print("\(strongSelf.aStr)")
}
真正造成泄漏。
我创建了一个演示App。 Root是一个navController
navController有一个根控制器。我们称之为buttonController。
单击buttonController中的按钮时,它会创建ViewController并推送到navController。
当您单击导航栏中的后退按钮时,navController会弹出您的ViewController实例。
对其进行剖析,然后您将在仪器中看到泄漏和保留周期。
iOS App的Xcode默认模板使用单个页面,它始终保留您的ViewController实例。如果ViewController实例仍然被系统使用,那么它实际上并不是泄漏。 所以推动&amp; pop为你泄露。