seems like the Swift equivalent of dealloc
is 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
从未被调用过?这是一个错误还是设计错误?
如果这是设计的,那么当不再需要视图控制器时,我应该在哪里放置清理代码以释放资源? (它不能放在viewDidUnload
中,因为该方法已被弃用。它不能出现在viewDidDisappear
中,因为其他内容可能会持有对它的引用,并最终会再次显示它。 )
注意:如果您尝试在Swift中定义dealloc
方法,则会收到以下错误:
方法' dealloc()'使用Objective-C选择器' dealloc'与使用相同的Objective-C选择器的deinitializer冲突。
如果Swift视图控制器继承自Objective-C控制器,并且在Objective-C dealloc方法中放置了断点,您将获得上面定义的相同错误行为:deinit
将不会调用,但dealloc
将被调用。
如果您尝试使用Allocations查看内存中类的实例数,则两个版本都显示相同的内容:# Persistent
始终为1,每次显示时# Transient
都会增加第二个视图控制器。
鉴于上述设置,视频控制器应该没有strong reference cycle。
答案 0 :(得分:30)
TLDR:
deinit
中有效。deinit
方法。感谢Adam for pointing me in the right direction。我没有做过大量的测试,但看起来deinit
中断点的行为与代码中的其他地方的行为不同。
我将向您展示几个示例,其中我在每个行号上添加了断点。那些可行的(例如暂停执行或执行其操作,如记录消息)将通过➤符号表示。
正常情况下,断点会被大量击中,即使方法无效:
➤ 1
➤ 2 func doNothing() {
➤ 3
➤ 4 }
5
但是,在空白deinit
方法中,否断点将会受到影响:
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
注意:对于在同一行暂停执行的断点,它们按创建顺序命中。为了测试他们的顺序,我设置了一个断点到日志消息和评估行动后自动继续。
注意:在我的测试中,还有另一个潜在的陷阱可能会让你:如果使用print("test")
,它会弹出调试区域以显示消息(消息以粗体显示) 。但是,如果您添加断点并告诉它记录消息,它将以常规文本记录它,不弹出打开调试区域。您必须手动打开调试区域才能看到输出。
注意:这都是在Xcode 7.1.1中测试的
答案 1 :(得分:5)