将 UINavigationController 与同一类的 UIViewControllers 实例一起使用,并且没有 NIB

Posted

技术标签:

【中文标题】将 UINavigationController 与同一类的 UIViewControllers 实例一起使用,并且没有 NIB【英文标题】:Using UINavigationController with UIViewControllers instances of the same class, and no NIB 【发布时间】:2010-10-28 15:57:28 【问题描述】:

在尝试基于 UINavigationController 的实验性 iPhone 应用程序时,当用户导航回上一个视图时遇到了问题。

简单的应用程序使用 UINavigationController,UIViewControllers 的新实例被推送到该控制器上。 这些实例都是同一个类(在本例中,类 MyViewController 是 UIViewController 的子类),并且是手动创建的(不使用 NIB)。每个实例都包含一个单独的 UITableView 实例作为 UIViewController 的视图。

以下 tableView:didSelectRowAtIndexPath: 方法来自 MyViewController 类。当用户选择表格单元格时,它会创建另一个 MyViewController 实例并将其推送到 navigationController:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    MyViewController *nextViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
    [self.navigationController pushViewController:nextViewController animated:YES];
    [nextViewController release];

用户可以在一系列视图中向前导航,每个视图都包含一个表格。导航回上一个屏幕时会出现此问题。应用程序中止,xcode 启动调试器。

可以通过不释放上面 tableView:didSelectRowAtIndexPath: 方法中的 MyViewController 实例,或者在 MyViewController 的 dealloc 方法中不调用 'myTableView' 实例的 dealloc 来防止错误。 然而,这不是一个真正的解决方案。据我所知, UINavigationController “拥有”推送的 UIViewController 实例,然后可以安全地从分配它的客户端释放。那么,这个实验性应用程序有什么问题呢?为什么当用户导航返回时它会终止?

下面是 MyViewController 类的一些其他方法:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) 
        self.title = @"My Table";
        myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        myTableView.delegate = self; 
        myTableView.dataSource = self;
        self.view = myTableView;
    
    return self;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyTable"];
    if (cell == nil)
    
        cell = [[UITableViewCell alloc] initWithFrame:CGRectMake(0,0, 300, 50) reuseIdentifier:@"MyTable"];
        [cell autorelease];
    
    cell.text = [NSString stringWithFormat:@"Sample: %d", indexPath.row];
    return cell;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return 3; // always show three sample cells in table


- (void)dealloc 
    [myTableView dealloc];
    [super dealloc];

编辑:

问题已解决 - 感谢 Rob Napier 指出问题。

-loadView 方法现在使用本地 UITableView 实例设置视图:

- (void)loadView 
    UITableView *myTableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    myTableView.delegate = self; 
    myTableView.dataSource = self;
    self.view = myTableView;
    [myTableView release];

【问题讨论】:

【参考方案1】:

您以错误的方法设置视图。你应该在-loadView 中设置它,而不是-initwithNibName:bundle:。查看视图控制器编程指南“使用视图控制器”中的示例。

【讨论】:

以上是关于将 UINavigationController 与同一类的 UIViewControllers 实例一起使用,并且没有 NIB的主要内容,如果未能解决你的问题,请参考以下文章

将 UIViewController 放在 UINavigationController 堆栈之上

将 UIViewController 添加到 UINavigationController 的问题

如何将 UIView 添加到 UINavigationController 堆栈

将 UINavigationBar 添加到没有 UINavigationController 的 UITableViewController

为啥我们将 UIViewController 传递给 UINavigationController 类?

如何将 CAGradientLayer 应用于 UINavigationController 背景