以编程方式创建的viewControllers的内存管理

时间:2012-02-09 03:35:28

标签: iphone memory viewcontroller addsubview

我意识到有很多类似于这个的问题,但是看了很多这些问题后,我仍然没有信心知道我做的是否正确。如果这个问题多余,我很抱歉,但我真的想确定我所做的事情是不是很糟糕的做法...

简要总结一下,我正在制作类似工具的应用程序,仅供我测试。底部有一个UIToolbar,带有一个按钮。在行为方面,当用户点击按钮时,它将在屏幕中间打开一个小的子视图。从本质上讲,它是一个设置子视图,用户可以在其中切换一些设置。如果用户再次单击工具栏按钮,则应关闭设置子视图。

无论如何,代码看起来像这样:

//Interface
@interface ViewController : UIViewController
{
    SettingsViewController *settingsViewController;
}
@property(retain, nonatomic) SettingsViewController *settingsViewController;

以下是实施:

//Implementation
-(IBAction)changeSettings:(id)sender
{
    if(!settingsViewController)
    {
        settingsViewController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil]; 

       //Do some stuff here with CGRect to put the subview in the center of the view

        [self.view addSubview:settingsViewController.view];
    }
    else
    {
        [settingsViewController.view removeFromSuperview];
        [settingsViewController release];
        [self setSettingsViewController:nil];
    }
}

实际上,现在使用此代码,当我尝试关闭子视图时崩溃(例如,当代码到达上面的else语句时,它会崩溃)。

查看上面的代码,我认为保留可能如下所示:

  • @property保留在settingsViewController上(保留为1)
  • 在settingsViewController(retain为2)上的alloc之后
  • 在addSubview之后:settingsViewcontroller.view(retain is 3)

我想我在这里做错了什么。或者更确切地说,我知道我是,因为它崩溃了。

我真的希望这是一个可以提出的问题。基本上,我想知道如何处理这样的情况。我以编程方式分配一个viewcontroller并执行addSubiew,但我想保留对该对象的引用,因为我需要在代码中的其他位置。处理这个问题的正确方法是什么?

谢谢!!

1 个答案:

答案 0 :(得分:1)

问题是你要多次发布settingsViewController。

if(!settingsViewController)
{
    settingsViewController = [[SettingsViewController alloc] initWithNibName:@"SettingsViewController" bundle:nil];
    // [settingsViewController retainCount] should now equal 1

    [self.view addSubview:settingsViewController.view];
}
else
{
    [settingsViewController.view removeFromSuperview];

    [settingsViewController release];
    // [settingsViewController retainCount] should now equal 0

    [self setSettingsViewController:nil];
    // [settingsViewController retainCount] should now equal -1. This is most
    // likely causing your crashes.
}

使用

[settingsViewController release];
settingsViewController = nil

或使用:

[self setSettingsViewController:nil];