[英]ViewController in navigation stack won't deinit when popped, causing memory leak
In my app I have a RootViewController
which all my ViewControllers are subclassed from. 在我的应用程序中,我有一个RootViewController
,我的所有ViewControllers都是子类。 When developing, I usually use this in my RootVC: 开发时,我通常在RootVC中使用它:
deinit {
print("\(type(of: self)) deinit")
}
so that I always can see when any of my viewControllers deinit. 这样我总能看到我的任何viewControllers何时出现。 It prints: 它打印:
MyExampleViewController deinit MyExampleViewController deinit
Today I noticed that one of them didn't deinit when I navigated away from it. 今天我注意到当我离开它时,其中一个没有离开。 Let's call it DetailViewController
. 我们称之为DetailViewController
。 It's a completely normal (Root)ViewController-subclass pushed into the main NavigationController
. 这是一个完全正常的(Root)ViewController子类,被推入主NavigationController
。 When hitting the Back button
in the navigation, it navigates away, but never says it deinits. 当点击导航中的Back button
时,它会导航,但从不说它会消失。 This is the first pushed controller, so I can't pop the controller before to see if that helps. 这是第一个推送控制器,所以我不能在之前弹出控制器,看看是否有帮助。 But any controller pushed after the DetailViewController
gets deinited fine when navigating back and forth. 但是,当DetailViewController
来回导航时,任何控制器都会被推动。
I decided to check the memory graph, so I ran my app again, pushed to the DetailViewController
, then popped it away by clicking the Back button
in the navigation, then I clicked Debug memory graph . 我决定检查内存图,所以我再次运行我的应用程序,推送到DetailViewController
,然后单击导航中的Back button
将其弹出,然后单击Debug memory graph 。
In the debug navigator on the left, I scroll down and see that there exists one instance of my DetailViewController
. 在左侧的调试导航器中,我向下滚动,看到我的DetailViewController
存在一个实例。 If I push back and forth several times before opening the memory graph, there are as many different instances of this DetailViewController
as times I've pushed and popped. 如果我在打开内存图之前来回移动几次,那么当我推送和弹出时,这个DetailViewController
实例就会多。
When clicking it, I see this: 点击它,我看到这个:
The DetailViewController
is the single controller on the far right. DetailViewController
是最右侧的单个控制器。 I haven't used Memory Graph that much, but I assume that the "solid" white lines are strong claims, and that the slightly more transparent (gray) lines are weak claims. 我没有那么多使用Memory Graph ,但我认为“实心”白线是强烈的主张,而稍微更透明(灰色)的线是弱主张。 Meaning that there's one strong claim to my controller. 这意味着我的控制器有一个强烈的主张。 The one on the bottom. 底部的那个。
What does this mean? 这是什么意思? It seems like my (custom) NavigationController
has an array called _childViewControllers
which retains my popped controller. 看起来我的(自定义) NavigationController
有一个名为_childViewControllers
的数组,它保留了我的弹出控制器。 To clarify, I don't have any stored variables in my custom NavigationController
. 为了澄清,我的自定义NavigationController
没有任何存储的变量。 It's only subclassed to override 5 functions, that is all. 它只是覆盖5个函数的子类,就是全部。 I have about 20 different ViewControllers
being pushed and popped by this exact same custom `NavigationController, but they all have no problem with this. 我有大约20个不同的ViewControllers
被这个完全相同的自定义`NavigationController推送和弹出,但它们都没有问题。
Am I reading the graph wrong? 我读图错了吗? There has to be a different strong claim that's not visible in the graph, right? 必须有一个不同的强烈主张,在图表中不可见,对吗? When I "pop" the viewController
by clicking Back
, shouldn't my viewController
be removed by _childViewControllers
? 当我“啪”的viewController
通过单击Back
,应该不是我viewController
被移除_childViewControllers
?
Figured it out at last. 终于搞清楚了。 Unfortunately, I had to go through commenting out several hundred lines of code bit by bit until I found out when it started to deinit when expected. 不幸的是,我不得不一点一点地评论几百行代码,直到我发现它何时开始在预期时去掉。 The issue was a missing [weak self]
in a closure, not unexpected, but it was in a completely different class, connected through a complicated hierarchy. 问题是在一个闭包中缺少[weak self]
,并不出乎意料,但它是在一个完全不同的类中,通过复杂的层次结构连接起来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.