UINavigationController 和 UIViewController 释放
我最近更改了我的应用程序以使用 UINavigationController,之前我使用的是 UINavigationBar,添加了级联子视图,这有点脆弱。
我面临内存使用问题。 Leaks 工具没有显示任何泄漏,但我创建并添加到 UINavigationController 的 ViewController 似乎从未被释放。因此,每次我创建一个新的 VC 然后按下 NavigationController 的后退按钮时,内存使用量都会增加。
我只是这样创建和添加我的 VC:
DetailViewController* detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
// setups
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
应用程序永远不会通过 ViewController 的dealloc 和viewDidUnload 方法。每次我按后退按钮时不应该调用这些吗?
我搜索了很多教程并阅读了Apple的内存管理,但是没有任何有关VC在使用NavigationController时在内存中的生命周期的信息。
I recently changed my app to use a UINavigationController, I was using a UINavigationBar before, with cascade subView adding, which was a bit tenuous.
I'm facing a problem of memory usage. Leaks tool doesn't show any leak, but ViewControllers I create and add to the UINavigationController never seem to be released. So memory usage grows everytime I create a new VC and then press the NavigationController's back button.
I simply create and add my VCs this way:
DetailViewController* detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
// setups
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
The app never goes through ViewController's dealloc
and viewDidUnload
methods. Shouldn't these be called everytime I press the back button?
I've searched many tutorials and read Apple's memory management, but there's nothing about VC's lifetime in memory when using NavigationController.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
也许您没有做错什么,而是面临类似 这个
在博客文章讨论的是我们是否必须手动释放 IBOutlets 的问题。事实证明我们应该这样做。这在 iOS 3.1.3 中是可以重现的,但我还没有在 iOS 4.0 中测试它。
第二种方法是重写视图控制器的保留和释放方法并打印出保留计数。我有一个类似的问题,一些视图控制器的 dealloc 方法没有调用,所以我重写这个方法来看看是否有人仍然保留它。事实证明确实如此。
编辑:
当我打印保留计数时,由于框架的原因,它有时会达到~98,所以不用担心。
如果你最后的保留计数保持在 2 并且 dealloc 方法不会被调用,那么有人仍然保留它。
在这种情况下,您应该在其他地方进行搜索。
例如我在同一问题中遇到的另一个问题:
有时我会使用
[NSTimerchedTimerWithTimeInterval:1.0 target:selfselector:@selector(updateUI) userInfo:nil Repeats:YES]
来不断更新 UI。但我忘记的是,NSTimer 将保留 target 对象(即 ViewController)。因为 NSTimer 保留了你的视图控制器,所以你的 dealloc 永远不会被调用,因为某人(NSTimer)仍然保留它。因此,您必须确保在 dealloc 方法之前使 NSTimer 无效才能正确释放视图控制器。
编辑2回应以下评论:
保留声明的属性的作用如下(示例):
因此它首先释放当前的 self.target,然后保留新值。由于您分配的是 nil,因此您的目标之后将为零。有关属性的更多信息可以在 Apple 文档中找到。
Maybe you are not doing something wrong and instead you are facing something like this
In the Blog post it was the question whether we have to manually release IBOutlets or not. As it turns out we should. This was reproduceable in iOS 3.1.3 but I didn't test it in iOS 4.0 yet.
The second aproach is to override your view controllers retain and release method and print out the retain count. I had a simimlar problem, that some view controllers dealloc method did not called so I override this methods to see wether someone has still a retain on it. As it turns out it did.
Edit:
When I printed my retain count, it would sometimes reach ~98 caused from the framework, so thats not really to worry.
If your last retain count stays at 2 and the dealloc method won't be called, than there is someone that has still a retain on it.
In this case you should search on other places.
For example another problem I encountered during this same problem:
Sometimes I would use
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateUI) userInfo:nil repeats:YES]
to constantly update the UI. But what I forgot was, that the NSTimer will retain the target object (which was the ViewController). Because the NSTimer retained your view controller your dealloc will never be called because someone (NSTimer) has still a retain on it. So you have to make sure to invalidate the NSTimer BEFORE dealloc method to properly release the view controller.
Edit2 in response for a comment below:
A retain declaired property does as follows (exsample):
So it does first release your current self.target then retains the new value. Since you are assigning nil your target will be nil afterwards. Further info about Properties can be found in the Apple doc.
我也见过这个。正如您所指出的,我在文档中没有看到任何明确的内容,但我相信它们会保留在内存中,直到需要内存为止。从性能角度来看,这是有意义的,因为这样做可以让应用程序在不同视图之间快速导航。
最重要的是,我不会担心这个。您可以在模拟器中发出一些低内存警告,看看它是否真正释放了您的 VC。
I have seen this as well. As you pointed out, I haven't seen anything definitive in the docs, but my belief is that they are retained in memory until memory is needed. It makes sense from a performance perspective as doing so allows the app to quickly navigate between the different views.
Bottom line is, I wouldn't worry about it. You could fire off some Low Memory Warnings in the Simulator and see if it actually releases your VCs.