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方法都被调用。
所以没有保留周期。
是吗?
发布于 2021-12-27 17:39:33
一个简单的方法,以确定你是否有一个保留周期是绘制一个图表。使用箭头表示强引用,使用虚线箭头表示弱/非拥有引用。
如果您可以跟随从一个对象返回到同一个对象的实体箭头,那么您就有了一个保留周期。
在您的例子中,A拥有B和C,B也拥有C,有2个拥有对C的引用,但没有“反向”强引用。没有办法让循环回到A或B,所以没有保留周期。
闭包是另一个不明显的保留周期的潜在来源。如果您有一个引用"self“的”转义“闭包,并且您持有对该闭包的强烈引用,那么您将有一个保留循环,因为您拥有对闭包的引用,而闭包通过它的self引用对您有很强的引用。
编辑:
我教新开发人员避免保留周期的方法是考虑“前进”和“反向”引用。前向引用应该是强引用,反向引用应该是弱引用。
如果您想到一个双链接列表,则前向指针应该是强的,而后面的指针应该是弱的。
如果您拥有一个对象,则指向它的指针应该是强的。如果您是该对象的委托,请将委托指针视为向后指针。它应该很弱。
https://stackoverflow.com/questions/70498211
复制相似问题