Sen*_*ful 19 memory-management objective-c uiviewcontroller ios swift
它看起来像雨燕相当于dealloc
ISdeinit
.但是,当您尝试在UIViewController上定义方法时,它的行为并不像您期望的那样......
建立
deinit
(Swift)或dealloc
(Objective-C)中放置一个断点.在VC2中,使"解除"按钮的操作执行以下操作:
// Swift:
presentingViewController?.dismissViewControllerAnimated(true, completion: nil)
// Objective-C:
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Run Code Online (Sandbox Code Playgroud)请注意,在Objective-C中,该dealloc
断点被击中.
在斯威夫特,在另一方面,该deinit
断点永远不会命中.
为什么deinit
从未打电话?这是一个bug还是设计?
如果这是设计的,那么当不再需要视图控制器时,我应该在哪里放置清理代码以释放资源?(它不能存在,viewDidUnload
因为该方法已被弃用.它不能存在,viewDidDisappear
因为其他东西可能持有对它的引用并最终再次显示它.)
注意:如果您尝试dealloc
在Swift中定义方法,则会收到以下错误:
使用Objective-C选择器'dealloc'的方法'dealloc()'与使用相同Objective-C选择器的deinitializer冲突.
如果Swift视图控制器继承自Objective-C控制器,并且在Objective-C dealloc方法中放置断点,您将获得上面定义的相同错误行为:deinit
将不会调用,但dealloc
将调用它.
如果您尝试使用Allocations查看内存中类的实例数,则两个版本都显示相同的内容:# Persistent
始终为1,# Transient
每次显示第二个视图控制器时增加.
鉴于上述设置,视图控制器应该没有强大的参考周期.
Sen*_*ful 31
TLDR:
deinit
前面有可执行代码行时才有效.deinit
方法.感谢Adam让我指出了正确的方向.我没有进行大量的测试,但看起来断点的行为与deinit
代码中的其他地方的行为不同.
我将向您展示几个示例,其中我在每个行号上添加了断点.那些将起作用的(例如暂停执行或执行其操作,如记录消息)将通过➤符号表示.
通常情况下,即使方法无效,断点也会受到严重影响:
? 1
? 2 func doNothing() {
? 3
? 4 }
5
Run Code Online (Sandbox Code Playgroud)
但是,在一个空白deinit
方法中,NO断点将会被击中:
1
2 deinit {
3
4 }
5
Run Code Online (Sandbox Code Playgroud)
通过添加更多行代码,我们可以看到它取决于断点后面是否有可执行的代码行:
? 1
? 2 deinit {
? 3 //
? 4 doNothing()
? 5 //
? 6 foo = "abc"
7 //
8 }
9
Run Code Online (Sandbox Code Playgroud)
特别是要密切关注第7和第8行,因为这与doNothing()
行为方式有很大不同!
如果您已经习惯了第4行断点的工作方式doNothing()
,那么如果在本例中第5行(甚至4)只有断点,则可能错误地推断出您的代码没有执行:
? 1
? 2 deinit {
? 3 number++
4 // incrementNumber()
5 }
6
Run Code Online (Sandbox Code Playgroud)
注意:对于在同一行上暂停执行的断点,它们将按创建顺序命中.为了测试他们的顺序,我设置了一个断点到Log Message并在评估操作后自动继续.
注意:在我的测试中,还有另一个潜在的陷阱可能会让你:如果你使用print("test")
,它会弹出Debug Area来显示消息(消息以粗体显示).但是,如果添加断点并将其告诉Log Message,它将以常规文本记录它,而不是弹出打开调试区域.您必须手动打开调试区域才能看到输出.
注意:这都在Xcode 7.1.1中进行了测试
归档时间: |
|
查看次数: |
19448 次 |
最近记录: |