弹出时未释放UIViewController [英] UIViewController not being released when popped

查看:65
本文介绍了弹出时未释放UIViewController的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表认为当选择小区它推视图控制器到导航堆栈:

I have a table view that when a cell is selected it pushes a view controller onto the navigation stack:

SAPostTableViewController *postViewController = [[SAPostTableViewController alloc] initWithNibName:NSStringFromClass([SAPostTableViewController class]) bundle:nil];
postViewController.site = site;
[self.navigationController pushViewController:postViewController animated:YES];
[postViewController release];

SAPostTableViewController具有一个静态tableView,它和它的单元格都是从笔尖加载的.

SAPostTableViewController has a static tableView which, and it's cells, are loaded from a nib.

我已经覆盖了initWithNibName:bundle:方法:

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        self.sections = [NSMutableDictionary dictionary];
    }
    return self;
}

sections是保留属性.

SAPostTableViewControllerviewDidLoad中,我有这个:

- (void)viewDidLoad
{
    [super viewDidLoad];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(cellVisibiltyChanged:) name:@"SAStaticCellVisibiltyChanged" object:nil];
}

,以便在viewDidUnload中进行匹配:

- (void)viewDidUnload
{
    [super viewDidUnload];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"SAStaticCellVisibiltyChanged" object:nil];
}

但是,当我按导航栏中的后退"按钮(所有标准行为,无替代)并且弹出SAPostTableViewController时,它不会调用viewDidUnloaddealloc.因此,这意味着如果我随后重新选择推动SAPostTableViewController的单元格,则会创建一个SAPostTableViewController的新实例,并前后重复此操作,这仅意味着内存使用率一直在增加,因为弹出的SAPostTableViewController从未被释放. (我通过在分配上运行Instruments知道这一点)

However when I press the back button in the navigation bar (all standard behaviour, no override) and SAPostTableViewController is popped, it doesn't call viewDidUnload or dealloc. So this means that if I then reselect the cell that pushes SAPostTableViewController it creates a new instance of SAPostTableViewController and repeating this back and forward just means the memory usage keeps increasing as the popped SAPostTableViewControllers never get deallocated. (I know this by running Instruments on allocations)

奇怪的是,如果我释放SAPostTableViewController两次,那么它将按我期望的那样工作:

The weird thing is that if I release SAPostTableViewController twice then it works as I'd expect:

SAPostTableViewController *postViewController = [[SAPostTableViewController alloc] initWithNibName:NSStringFromClass([SAPostTableViewController class]) bundle:nil];
postViewController.site = site;
[self.navigationController pushViewController:postViewController animated:YES];
[postViewController release];
[postViewController release];

(如果我添加了第三条发布语句,那么它就会崩溃,就像我期望的那样只有2条)

(If I add a third release statement, it crashes as I'd expect it to with just 2)

我求助于retainCount并逐步执行在上面直接代码的第一行中执行的代码行,retainCount保持为1.它在第一行和第二行之间跳转,因此我可以看不到保留多余时间的地方吗?

I have resorted to using retainCount and stepped through the lines of code the are executed in the first line of the directly above code, the retainCount remains at 1. It jumps up between the first and second line, so I can't see anywhere it is being retain an extra time?

SAPostTableViewController仅在此位置使用,它不是任何东西的委托,也没有委托.

The SAPostTableViewController is only used in this place, it is not a delegate of anything, nor does it have a delegate.

如何找到修复程序,或者我错过了一些简单的事情?

How can I find a fix, or is it something simple I've missed?

这是Instruments在仅推送SAPostTableViewController一次(只有一个release语句)后显示的内容:

Here is what Instruments shows after pushing SAPostTableViewController just once (with only one release statement):

以及反复来回导航后显示的内容(再次,一条release语句):

And what it shows after navigating back and forth repeatedly (again, one release statement):

推荐答案

我不知道您的问题是什么,但是这里有一些需要考虑的事情:

I don't know what your problem is, but here are some things to consider:

  1. 您绝对应该不要两次释放视图控制器.如果确实在UIKit中发现了内存泄漏(这种情况不太可能发生),则很有可能在UIKit的未来版本中将其修复.这意味着在新版本的操作系统上运行旧版本应用程序的任何人都不会遭受崩溃(由于过度释放视图控制器).泄漏比崩溃更好.泄漏的应用程序仍然是可用的应用程序(至少在泄漏过多之前).但是崩溃的应用程序根本无法运行.

  1. You should absolutely NOT release the view controller twice. If you have indeed discovered a memory leak in UIKit (which is unlikely), then it is likely it would be fixed in a future version of UIKit. That means that anyone running an old version of your app on a new version of the operating system would experience nothing but crashes (due to over-releasing the view controller). It is better to leak than to crash. A leaky app is still a usable app (at least until you leak too much). But a crashing app can't be run at all.

-viewDidUnload并没有按照您认为的方式做.仅在由于内存压力卸载视图控制器的视图时才调用它.在正常释放期间不会调用它.改为依赖-viewWillAppear:-viewDidDisappear:是更明智的.

-viewDidUnload is not doing what you think it should be doing. It is only called when the view controller's view is unloaded due to memory pressure. It is not called during normal deallocation. It would be wiser to rely on -viewWillAppear: and -viewDidDisappear: instead.

这篇关于弹出时未释放UIViewController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆