【问题标题】:When to release UINavigationController when created from UITableViewController?从 UITableViewController 创建时何时释放 UINavigationController?
【发布时间】:2012-09-13 06:25:33
【问题描述】:

我的情况很不寻常,我不太了解内存管理。

我有一个 UITableViewController 用于显示消息,然后创建一个 UINavigationController 并将其视图添加为当前视图的子视图以显示它。我遇到的问题是 Xcode 报告我有潜在的内存泄漏(我同意),因为没有释放 UINavigationController,但是当我按照下面的代码释放它时,当我点击返回返回到表格视图。

我在 UITableViewController 中使用了一个保留属性来跟踪当前 UINavigationController 并管理保留计数,但显然我在这里遗漏了一些东西。

注意:单击返回按钮时会发生崩溃,并显示消息 -[UILayoutContainerView removeFromSuperview:]: unrecognized selector sent to instance 0x5537db0

另外请注意,如果我删除 [nc release] 代码行,它就可以正常工作。

这是我的代码:

@property(nonatomic, retain) UINavigationController *currentNavigationController;

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UINavigationController *nc = [[UINavigationController alloc] init];

    CGRect ncFrame = CGRectMake(0.0, 0.0, [[self view] frame].size.width, [[self view] frame].size.height);
    [[nc view] setFrame:ncFrame];

    // I created a CurrentNavigationController property to 
    // manage the retain counts for me
    [self setCurrentNavigationController:nc]; 

    [[self view] addSubview:[nc view]];
    [nc pushViewController:messageDetailViewController animated:YES];


    UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonSystemItemRewind target:[nc view] action:@selector(removeFromSuperview:)];


    nc.navigationBar.topItem.leftBarButtonItem = bbi;
    [bbi release];

    [nc release];
}

【问题讨论】:

    标签: ios


    【解决方案1】:

    您创建的 UINavigationController "nc" 只能在此方法中使用。在此方法之后它不会存储在任何地方(因为您释放它)。因此,您将navigationController 的视图作为子视图添加到您的类视图中,然后删除navigationController。那是错误的。当视图和视图控制器尝试引用它们的导航控制器时(当它不存在时),您的应用将崩溃。

    这里是 didSelectRowForIndexPath 方法的代码:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    {
    
        UINavigationController *nc = [[UINavigationController alloc] init];
    
        CGRect ncFrame = CGRectMake(0.0, 0.0, [[self view] frame].size.width, [[self view] frame].size.height);
        [[nc view] setFrame:ncFrame];
    
        [self setCurrentNavigationController:nc]; 
        [nc release];
    
        [[self view] addSubview:[self.currentNavigationController view]];
    
        UIViewController *viewCont = [[UIViewController alloc] init];
        [viewCont.view setBackgroundColor:[UIColor greenColor]];
    
        [nc pushViewController:viewCont animated:YES];
    
        NSLog(@"CLASS %@",[[self.currentNavigationController view]class]);
    
        UIBarButtonItem *bbi = [[UIBarButtonItem alloc] initWithTitle:@"Back" style:UIBarButtonSystemItemRewind target:[self.currentNavigationController view] action:@selector(removeFromSuperview)];
    
    
        self.currentNavigationController.navigationBar.topItem.leftBarButtonItem = bbi;
        [bbi release];
    }
    

    removeFromSuperview 方法的选择器最后不应该有“:”。它没有参数:)

    【讨论】:

    • 首先没有注意到您的财产...我认为,应用程序崩溃了,因为创建了新的导航控制器。当您将其分配给您的财产时,旧的将被删除,并且它的所有视图都未处理...
    • 我编辑了我的代码,以显示单击“后退”按钮时如何弹出视图。当添加新的导航控制器时,视图应该都消失了。但是,值得注意的是,当单击返回按钮时,应用程序会崩溃。
    • 工作就像一个魅力。关键是 removeFromSuperView 中多余的冒号!
    猜你喜欢
    • 2011-10-07
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多