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

Iphone 以编程方式创建的ViewController的内存管理,iphone,memory,viewcontroller,addsubview,Iphone,Memory,Viewcontroller,Addsubview,我意识到有许多问题与此类似,但在仔细阅读了其中的许多问题后,我仍然缺乏信心去知道我所做的是否正确。如果这个问题是多余的,我很抱歉,但是我真的很想确定我所做的是否是不好的实践 简而言之,我正在制作一个类似工具的应用程序,只是为了测试。底部有一个带按钮的UIToolbar。在行为方面,当用户点击按钮时,它会在屏幕中间打开一个小的子视图。本质上,它是一个设置子视图,用户可以在其中切换一些设置。如果用户再次单击工具栏按钮,则应关闭“设置”子视图 无论如何,代码如下所示: //Interface @int

我意识到有许多问题与此类似,但在仔细阅读了其中的许多问题后,我仍然缺乏信心去知道我所做的是否正确。如果这个问题是多余的,我很抱歉,但是我真的很想确定我所做的是否是不好的实践

简而言之,我正在制作一个类似工具的应用程序,只是为了测试。底部有一个带按钮的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语句时,它崩溃了)

看看上面的代码,我想代码可能是这样的:

//Interface
@interface ViewController : UIViewController
{
    SettingsViewController *settingsViewController;
}
@property(retain, nonatomic) SettingsViewController *settingsViewController;
  • @设置ViewController时的属性保留(保留为1)
  • 设置VIEWCONTROLLER(保留为2)上的alloc后
  • 添加子视图后:设置viewcontroller.view(保留为3)
我想我做错了什么。或者更确切地说,我知道我是,因为它正在崩溃

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


谢谢

问题是您释放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];

非常感谢。但是,我有一个问题需要澄清:在这一行之前:settingsViewController=[[settingsViewController alloc]initWithNibName:@“settingsViewController”bundle:nil];由于@property(retain),retain计数不是已经是1了吗?那么按照上面的alloc,retain count不是变为2吗?在这个特定的实例中,您在分配和初始化setingsviewcontroller时没有调用属性。如果您使用了行
self.settingsViewController=[[settingsViewController alloc]initWithNibName:@“settingsViewController”bundle:nil]你是对的,保留计数为2。您在分配控制器时将其保留为普通ivar,但在解除分配时将其视为ivar和属性。谢谢!我不知道那是关于self.settingsViewController的。如果我可以问一下,在这种情况下,哪种方法是正确的?我应该按照上面的说明去做,还是做一些完全不同的事情呢?这取决于你是如何使用房产的。我通常在类中手动管理发布,除非我使用setter方法来自动执行其他任务。