4

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];

SAPpostTableViewController 有一个静态的 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是保留财产。

在我有这个viewDidLoadSAPostTableViewController

- (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 永远不会被释放。(我通过在分配上运行 Instruments 知道这一点)

奇怪的是,如果我两次发布 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。它在第一行和第二行之间跳跃,所以我看不到它在任何地方被保留额外的时间?

SAPpostTableViewController 只用在这个地方,它不是任何东西的委托,也没有委托。

我怎样才能找到解决方法,还是我错过了一些简单的东西?

以下是 Instruments 在推送一次 SAPostTableViewController 后显示的内容(只有一个发布声明): 在此处输入图像描述

以及反复来回导航后显示的内容(再次,一个发布声明): 在此处输入图像描述

4

2 回答 2

0

当您单击一个单元格时,您正在创建一个新对象,为什么您不在SAPostTableViewControllerinit 方法中创建您的对象()然后推送您在单元格中单击的相同对象观看时间

你可以这样做:

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]; 

    } 
于 2012-05-19T11:25:44.927 回答
0

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

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

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

于 2012-05-19T15:14:36.687 回答