UINavigationController和内存管理

时间:2010-05-12 14:19:00

标签: iphone memory-management uinavigationcontroller

- (void)launchSearch 
{
 EventsSearchViewController *searchController = [[EventsSearchViewController alloc] initWithNibName:@"EventsSearchView" bundle:nil];
 [self.navigationController pushViewController:searchController animated:YES];
 //[searchController release]; 
}

请注意,[searchController release]已被注释掉。我知道将searchController推送到导航控制器会保留它,我应该从我的代码中释放它。毕竟,我只是分配/初始化它,如果我不释放它,它就会泄漏。

随着该系列的注释,导航效果很好。如果没有注释掉,我可以正确浏览INTO这个视图,但是返回一个级别崩溃并出现*** -[CFArray release]: message sent to deallocated instance 0x443a9e0错误。

这里发生了什么?当它离开视图时,NavigationController是否会以某种方式为我发布它?

XCode中的UINavigationController模板上的样板文件已经释放了新推送的控制器。但是当我这样做时,它失败了。

--- ---- EDIT

所以今天早上,我坐下来,它有效。没有真正的线索为什么。叹息。

按照我以为我学到的东西,然后将它应用到同一个控制器的另一个部分,我做了以下操作。昨天我有这个代码没有发布声明,因为它不能正常使用它们。所以今天早上我添加了它们来创建:

- (IBAction)switchView:(id)sender
{
    UISegmentedControl *seg = (UISegmentedControl *)sender;
    NSInteger choice = [seg selectedSegmentIndex];

    NSArray *array = [mainView subviews];
    UIView *oldView = [array objectAtIndex:0];
    [oldView removeFromSuperview];

    if (choice == 0) {
        tableController = [[EventsTableViewController alloc]
            initWithNibName:@"EventsTableView" bundle:nil];
            [mainView addSubview:tableController.view];
            [tableController release];
    }

    if (choice == 1) {
        calendarController = [[EventsCalendarViewController alloc]
            initWithNibName:@"EventsCalendarView" bundle:nil];
        [mainView addSubview:calendarController.view];
        [calendarController release];
    }
    if (choice == 2) {
        mapController = [[EventsMapViewController alloc]
            initWithNibName:@"EventsMapView" bundle:nil];
        [mainView addSubview:mapController.view];
        [mapController release];
    }
}

随着它设置如此,当我进入视图时,我的视图的主门户充满了EventsTableViewController的视图,我可以点击mapView和calendarView,但是当我回到tableView时,我死了,因为正在释放的实例上调用表委托方法。

所以我把所有这些控制器都变成了合成属性,所以我可以在[dealloc]中释放它们。这似乎有用,但真正的问题是为什么添加这些视图作为子视图不会保留它们,将所有权传递给它所属的新视图,允许我在那里发布它们?

3 个答案:

答案 0 :(得分:1)

哇,伙计们。非常感谢您的所有回复 - 可悲的是,我发送了所有可怕的回复。

我的NavigationView导航事件对象的NSArray(本地艺术活动)。我的表格视图向下钻取到详细视图。

我的详细视图包含以下内容:

-(void)loadEvent:(Event *)event
{
    thisEvent = event;          
}

在将细节视图推送到导航堆栈之前,我从表格视图中调用它。 thisEvent是Event类型的合成属性,因此,由于它是合成的,我在release中尽职尽责[dealloc]

你们许多人已经看到了这个问题。备份到表视图,当我滚动显示我刚刚看到的那个时,它会构建自定义表行,所以它从事件中获取title属性....我刚刚在详细信息中发布控制器。吊杆。

我在上面的loadEvent:方法中添加了retain并且崩溃了,它们就消失了。

没有这个真的是关于navcontroller保留和发布的观点。这是关于意外地过度释放我正在导航的数据对象。我发现这一点的部分原因是,我自己在每个视图控制器的[dealloc]中进行了NSLog,我现在可以看到它们的行为完全正确。

谢谢!我喜欢这个网站。

答案 1 :(得分:0)

我猜错误在于EventsSearchViewController的init。它错误地归还了自我释放的自我吗?

答案 2 :(得分:0)

看起来EventsSearchViewController正在分配一个数组,然后过度释放它,其中一个版本可能在其dealloc中。

如果您注释掉release,则EventsSearchViewController永远不会被取消分配(它会泄漏)。因此,由于不会调用该方法,因此将隐藏由于其自身dealloc而发生的错误。释放控制器是正确的,但是控制器本身还有另一个错误,它只出现在dealloc时间。

也可能是dealloc正在发布一个自动释放的数组,因此您的代码中可能没有两个显式的释放调用。但它看起来非常像在dealloc中释放导致问题的东西。