iOS ARC:使用 deinit 保留循环?
iOS ARC: retain cycle with deinit?
iOS 保留周期:
典型的例子是A有B,B有A。
那如果A有B&C,B有C呢?
是否还保留循环?
当保留循环存在时,deinit
不会被 ARC
调用是否有很强的关系?
示例代码如下:
class ViewModel{
func doSth(){
print("123")
}
deinit{
print("ViewModel")
}
}
class CustomView: UIView{
var viewModel: ViewModel?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
viewModel?.doSth()
}
deinit{
print("CustomView")
}
}
class ViewController: UIViewController {
var viewModel = ViewModel()
lazy var widget: CustomView = {
let v = CustomView(frame: CGRect(origin: .zero, size: CGSize(width: 150, height: 150)))
v.backgroundColor = UIColor.red
v.viewModel = viewModel
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(widget)
}
deinit{
print("ViewController")
}
}
当ViewController
弹出时,上面的三个deinit
方法都被调用了。
所以没有保留周期。
是吗?
判断是否有保留循环的一个简单方法是画一个图表。使用箭头表示强引用,使用虚线箭头表示 weak/unowned 个引用。
如果您可以沿着实线箭头从一个对象返回到同一对象,那么您就有了一个保留周期。
在你的例子中,A 拥有 B 和 C,B 也拥有 C,有 2 个拥有对 C 的引用,但没有“向后”强引用。您无法循环回到 A 或 B,因此没有保留周期。
闭包是另一个不明显的保留循环的潜在来源。如果你有一个引用“self”的“转义”闭包,并且你持有对该闭包的强引用,那么你就有一个保留周期,因为你有一个对闭包和闭包的拥有引用,通过它的 self
引用, 对你有很强的参考意义。
编辑:
我教新开发人员避免保留循环的方法是根据“前向”和“后向”引用来思考。前向引用要强,后向引用要弱
如果你想到一个双向链表,前向指针应该是强的,而后向指针应该是弱的。
如果您拥有一个对象,您指向它的指针应该是强指针。如果您是该对象的代表,请将代表指针视为向后指针。应该是弱点。
iOS 保留周期:
典型的例子是A有B,B有A。
那如果A有B&C,B有C呢?
是否还保留循环?
当保留循环存在时,deinit
不会被 ARC
调用是否有很强的关系?
示例代码如下:
class ViewModel{
func doSth(){
print("123")
}
deinit{
print("ViewModel")
}
}
class CustomView: UIView{
var viewModel: ViewModel?
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
viewModel?.doSth()
}
deinit{
print("CustomView")
}
}
class ViewController: UIViewController {
var viewModel = ViewModel()
lazy var widget: CustomView = {
let v = CustomView(frame: CGRect(origin: .zero, size: CGSize(width: 150, height: 150)))
v.backgroundColor = UIColor.red
v.viewModel = viewModel
return v
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(widget)
}
deinit{
print("ViewController")
}
}
当ViewController
弹出时,上面的三个deinit
方法都被调用了。
所以没有保留周期。
是吗?
判断是否有保留循环的一个简单方法是画一个图表。使用箭头表示强引用,使用虚线箭头表示 weak/unowned 个引用。
如果您可以沿着实线箭头从一个对象返回到同一对象,那么您就有了一个保留周期。
在你的例子中,A 拥有 B 和 C,B 也拥有 C,有 2 个拥有对 C 的引用,但没有“向后”强引用。您无法循环回到 A 或 B,因此没有保留周期。
闭包是另一个不明显的保留循环的潜在来源。如果你有一个引用“self”的“转义”闭包,并且你持有对该闭包的强引用,那么你就有一个保留周期,因为你有一个对闭包和闭包的拥有引用,通过它的 self
引用, 对你有很强的参考意义。
编辑:
我教新开发人员避免保留循环的方法是根据“前向”和“后向”引用来思考。前向引用要强,后向引用要弱
如果你想到一个双向链表,前向指针应该是强的,而后向指针应该是弱的。
如果您拥有一个对象,您指向它的指针应该是强指针。如果您是该对象的代表,请将代表指针视为向后指针。应该是弱点。