将UIViewController添加到子视图并删除它的最正确方法是什么?

时间:2012-04-18 17:39:15

标签: ios uiviewcontroller release-management addsubview memory-management

我正在尝试添加一个UIViewController子视图,然后单击一个按钮关闭它。我目前的代码完成了这项工作,我只是不确定它是否会泄漏或导致任何问题。

首先我添加子视图

-(IBAction)openNewView:(id)sender{
   // start animation
   [UIView beginAnimations:@"CurlUp" context:nil];
   [UIView setAnimationDuration:.3];
   [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
   [UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];

   // add the view
   newViewController* newVC = [[newViewController alloc] initWithNibName:@"newViewController" bundle:[NSBundle mainBundle]];
   [self.view addSubview:newVC.view];

   [UIView commitAnimations]; 
}

然后在newViewController.m中我有删除它的功能

-(IBAction)closeNewView:(id)sender{
   // start animation
   [UIView beginAnimations:@"curldown" context:nil];
   [UIView setAnimationDelegate:self];
   [UIView setAnimationDuration:.3];
   [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
   [UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:self.view.superview cache:YES];

   // close dialog
   [self.view removeFromSuperview];
   [UIView commitAnimations];

   [self.view release];
}

就像我说的那样有效,但是当我分析代码时,它告诉我:

在X行分配的对象可能泄漏并存储到'newViewController'中:

newViewController* newVC = [[newViewController alloc] initWithNibName:@"newViewController" bundle:[NSBundle mainBundle]];

[self.view release];

的调用者此时不拥有的对象的引用计数的不正确递减

如果我autorelease viewController而不是[self.view release]它在删除时崩溃(如果我在添加后释放视图),它会崩溃: - [FirstViewController performSelector:withObject:withObject:]:message to sent to解除分配的实例0xd21c7e0

如果我在viewControllers [newVC release]中调用dealloc,则无法构建。

希望我没有提出一个相当明显的问题,但添加和删除viewControllers的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

您使用的是哪种IOS版本?如果您使用的是5.0,那么您应该继续切换到ARC,这样您就不必自己处理[release]调用了。

如果您仍然希望或需要坚持手动内存管理:如果您尝试发布newVC,则dealloc无法构建的原因是因为该指针的作用域是openNewView函数。使它成为一个类成员,你就可以发布它。

@implementation WhateverItsCalled {
  newViewController *newVC;
}

- ( IBAction ) openNewView: (id)sender {
...
  newVC = [ [ newViewController alloc ] initWithNibNamed:...
}

- ( void ) dealloc {
  [ newVC release ];
}

是的,如果您不使用ARC,则每个“alloc”必须与相应的“发布”配对。

另外我必须问 - 为什么你在这里使用视图控制器?如果您只想要一个视图,可以使用[[NSBundle mainBundle] loadNibNamed]从NIB加载视图,并将[self]列为文件的所有者。这将设置所有引用(包括您想要的视图),并且您不必实例化(看起来像什么)一个多余的视图控制器。