弹出时不会释放UIViewController

时间:2012-05-19 11:17:33

标签: objective-c memory-management

我有一个表格视图,当选择一个单元格时,它会将一个视图控制器推送到导航堆栈:

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

SAPostTableViewController有一个静态tableView,它的单元格是从nib加载的。

我已覆盖initWithNibName:bundle:方法:

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

sections是保留的财产。

viewDidLoad SAPostTableViewController我有这个:

- (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 s而不断增加永远不会被解除分配。 (我通过在分配上运行仪器来了解这一点)

奇怪的是,如果我发布两次SAPostTableViewController,那么它就像我期望的那样工作:

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

(如果我添加第三个发布声明,它会因为我预期只有2而崩溃)

我已经使用retainCount并逐步执行在上面代码的第一行中执行的代码行,retainCount保持为1.它在第一行和第二行之间跳转,所以我什么都看不到它会留出多余的时间?

SAPostTableViewController仅在此处使用,它不是任何内容的委托,也不具有委托。

我怎样才能找到解决方案,或者我错过了哪些简单的东西?

以下是在推送SAPostTableViewController一次之后显示的内容(只有一个发布语句): enter image description here

反复导航后再显示的内容(同样,一个发布声明): enter image description here

2 个答案:

答案 0 :(得分:0)

当您使用一个Cell时,您正在创建一个新对象,为什么不在init方法中创建对象(SAPostTableViewController),然后在单元格中单击相同的对象观察时间

你可以这样做:

postViewController = [[SAPostTableViewController alloc] initWithNibName:NSStringFromClass([SAPostTableViewController class]) bundle:nil];

并在

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 
postViewController.site = site; 
[self.navigationController pushViewController:postViewController animated:YES]; [postViewController release]; 

    } 

答案 1 :(得分:0)

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

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

  2. -viewDidUnload没有做你认为它应该做的事情。仅在由于内存压力而卸载视图控制器的视图时调用它。在正常释放期间不会调用它。明确依靠-viewWillAppear:-viewDidDisappear:

  3. 会更明智