[英]Deinit not called on a UIViewController, but Dealloc is
似乎deinit
相当于dealloc
是deinit
。 但是,当您尝试在UIViewController上定义方法时,它的行为并不像您期望的那样......
建立
deinit
(Swift)或dealloc
(Objective-C)中放置一个断点。 在VC2中,使“解除”按钮的操作执行以下操作:
// Swift: presentingViewController?.dismissViewControllerAnimated(true, completion: nil) // Objective-C: [self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
注意在Objective-C中 ,如何命中dealloc
断点 。
另一方面,在Swift中 , deinit
断点永远不会被击中 。
为什么deinit
从未被叫过? 这是一个bug还是设计?
如果这是设计的,那么当不再需要视图控制器时,我应该在哪里放置清理代码以释放资源? (它不能在viewDidUnload
因为该方法已被弃用。它不能在viewDidDisappear
因为其他东西可能持有对它的引用并最终再次显示它。)
注意:如果您尝试在Swift中定义dealloc
方法,则会收到以下错误:
使用Objective-C选择器'dealloc'的方法'dealloc()'与使用相同Objective-C选择器的deinitializer冲突。
如果你有斯威夫特视图控制器从一个Objective-C控制器继承,你把一个断点在Objective-C的dealloc方法,您将获得上述相同的错误行为:在deinit
不会被调用,而dealloc
会调用。
如果您尝试使用Allocations查看内存中类的实例数,则两个版本都显示相同的内容: # Persistent
始终为1,每次显示第二个视图控制器时# Transient
增加。
鉴于上述设置,视图控制器应该没有强大的参考周期 。
TLDR:
deinit
中deinit
。 deinit
方法。 感谢Adam让我指出了正确的方向 。 我没有做广泛的测试,但它看起来像断点行为不同deinit
不是在你的代码在其他地方。
我将向您展示几个示例,其中我在每个行号上添加了断点。 那些将起作用的(例如暂停执行或执行其操作,如记录消息)将通过➤符号表示。
通常情况下,即使方法无效,断点也会受到严重影响:
➤ 1
➤ 2 func doNothing() {
➤ 3
➤ 4 }
5
但是,在一个空白的deinit
方法中, NO断点将会被击中:
1
2 deinit {
3
4 }
5
通过添加更多行代码,我们可以看到它取决于断点后面是否有可执行的代码行:
➤ 1
➤ 2 deinit {
➤ 3 //
➤ 4 doNothing()
➤ 5 //
➤ 6 foo = "abc"
7 //
8 }
9
特别是要密切关注第7行和第8行,因为这与doNothing()
行为的方式有很大不同!
如果您已经习惯了第4行断点在doNothing()
,那么如果在本例中第5行(甚至4)只有断点,则可能会错误地推断出您的代码没有执行:
➤ 1
➤ 2 deinit {
➤ 3 number++
4 // incrementNumber()
5 }
6
注意:对于在同一行上暂停执行的断点,它们将按创建顺序命中。 为了测试他们的顺序,我设置了一个断点到Log Message并在评估操作后自动继续 。
注意:在我的测试中还有另一个潜在的陷阱可能会让你:如果你使用print("test")
,它会弹出Debug Area来显示消息(消息以粗体显示)。 但是,如果添加断点并将其告诉Log Message ,它将以常规文本记录它,而不是弹出打开调试区域。 您必须手动打开调试区域才能看到输出。
注意:这都在Xcode 7.1.1中进行了测试
我还没有尝试过,但我确实为你找到了这个 :
看起来函数不会被调用,除非一些代码被放入deinit(怪异)必须是swift的优化阶段的一部分。
尝试按照建议在您的deinit中放置打印声明并报告您的发现
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.