我发现在以下场景下,我的UIViewcontroller没有调用deInit()
。我正在使用这个代码扩展,通过添加敲击手势识别器来使我的生活更轻松。
https://gist.github.com/Saoudrizwan/548AA90BE174320FBAA6B3E71F01F6AE
我在我的一个风险投资公司中使用了这段代码,我把它精简到了最小的代码量:
在viewdidload()
中,我执行了以下操作:
// When the user taps on a label, have its related textbox automatically get the caret so they can type
// Add tapping so when you tap on a label it makes the corresponding textbox first responder
lblSubject.addTapGestureRecognizer {
self.txtSubject.becomeFirstResponder()
}
这一行似乎是:
self.txtSubject.becomeFirstResponder()
问题是--当我在闭包中留下上面的这一行时,deinit()
不会在我的VC中调用。当我取出上面的行或用类似print(“Hello World”)
deInit()
的东西替换它时,会正确地调用。txtSubject是@IBOutlet弱var txtSubject:uitextfield!
我不完全确定在这里做什么。我读到,当您触发becomefirstresponder()
时,调用regish firstresponder()
是很重要的,但即使我没有点击标签(这样就不会给becomefirstresponder()
连调用的机会),我仍然无法点击deinit()
有什么我可以看得更远的地方吗?
非常感谢。
这是一个典型的保留循环。闭包中的self.
提醒您考虑这一点。我假设self
保留了LBLSubject
,并且(通过一个objc_association_retrain
关联的键),LBLSubject
保留了self
,因为它被这个闭包捕获。
但是,这里并不需要self
。您只需要txtsubject
。所以你可以捕捉到:
lblSubject.addTapGestureRecognizer { [txtSubject] in
txtSubject.becomeFirstResponder()
}
或者,您可以回到巨大的弱自
锤子(尽管这往往被过度使用):
lblSubject.addTapGestureRecognizer { [weak self] in
self?.txtSubject.becomeFirstResponder()
}
探索这类bug的最好方法是使用Xcode的内存图。
回顾一下关于自动引用计数的Swift文档也是一个好主意。