如何解决Deinit 未调用 - 找不到保留某些内容的原因提供代码
我发现在以下情况下我的 UIViewcontroller 没有调用 deinit()
。
我正在使用此代码扩展通过添加点击手势识别器来让我的生活更轻松。
https://gist.github.com/saoudrizwan/548aa90be174320fbaa6b3e71f01f6ae
我在我的一个 VC 中使用了此代码,我已将其精简到最少的代码量:
在 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 weak var txtSubject: UITextField!
我不完全确定在这里做什么。我读到当你触发 becomeFirstResponder()
时调用 resignFirstResponder()
很重要,但即使我不点击标签(以免给 becomeFirstResponder()
甚至调用的机会)我仍然无法点击deinit()
有什么想法可以让我看得更远吗?
非常感谢。
解决方法
改变
self.txtSubject.becomeFirstResponder()
到
[unowned self] in self.txtSubject.becomeFirstResponder()
unowned
通常被认为是危险的,但这里没有危险。如果 self
不复存在,将没有任何东西可以点击,代码将永远不会运行。
这是一个经典的保留循环。闭包内的 self.
是为了提醒您考虑这一点。我假设 self
保留 lblSubject
,并且(通过 OBJC_ASSOCIATION_RETAIN
关联键),lblSubject
保留 self
因为它被这个闭包捕获。>
然而,您在这里并不真正需要 self
。你只需要txtSubject
。所以你可以捕捉它:
lblSubject.addTapGestureRecognizer { [txtSubject] in
txtSubject.becomeFirstResponder()
}
或者,您可以退回到巨大的 weak self
锤子(尽管这往往被过度使用):
lblSubject.addTapGestureRecognizer { [weak self] in
self?.txtSubject.becomeFirstResponder()
}
探索此类错误的最佳方法是使用 Xcode 的 Memory Graph。
查看 Automatic Reference Counting 上的 Swift 文档也是一个好主意。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。