通常,当我使用将当前视图控制器推开的视图控制器时,我使用UINavigationController并推送/弹出新的视图控制器,让它们自己处理所有批处理。
但是,例如,在本例中,我有一个 MainViewController,这是应用程序启动时的默认视图。 我有第二个视图,称为 SecondaryViewController,它是主屏幕上的弹出窗口(有点像灯箱(。
下面是用于说明的代码:
//From within mainViewController:
secondaryViewController = [SecondaryViewController alloc] initWithNibName:@"SecondaryViewController" bundle:nil];
[self.view addSubview:secondaryViewController.view];
辅助视图控制器接口如下所示:
//interface
@interface SecondaryViewController : UIViewController
{
IBOutlet UILabel *httpLabel;
IBOutlet UIScrollView *scrollView;
}
@property(retain, nonatomic) IBOutlet UILabel *httpLabel;
@property(retain, nonatomic) IBOutlet UIScrollView *scrollView;
至于实现,我有@property
ivars的@synthesize
,但我没有做任何手动分配。 但是,我确实放了一个 dealloc 方法:
- (void)dealloc
{
[httpLabel release];
[scrollView release];
[super dealloc];
}
但我不确定我需要上述内容。
所以我的问题如下:
1( 在这种情况下,我需要上述 dealloc 方法吗? 或者更一般地说,子视图何时需要 dealloc 方法?
2( 如果我需要或不需要它,是否取决于我是通过addSubview还是pushViewController添加辅助视图控制器? 例如,如果我想替换整个主视图控制器,则如下所示:
[self.navigationController pushViewController:secondaryViewController animated:NO]
辅助视图控制器是否需要 dealloc 方法?
谢谢!
是的,在这种情况下,您确实需要完全按照您拥有的 dealloc 方法。 您走在正确的轨道上,因为您假设由于您没有进行任何手动分配,因此您无需执行任何 dealloc/release ...但是,通过将属性指定为 (保留,非原子(,您将执行隐式保留。
这意味着,如果您设置了这些属性,则在幕后实际发生的事情是这样的:
-(void)setHttpLabel:(UILabel *)newlabel
{
if (newLabel != httpLabel)
{
[httpLabel release];
httpLabel = [newLabel retain];
}
}
如您所见,您的合成导致对象上发生保留。如果你从不平衡保留与释放,它就会泄漏。 因此,唯一合乎逻辑的地方是在您的 dealloc 方法中。 这创造了生命的循环。
如果您从未设置过这些属性并且在 dealloc 中没有发布,那么它不会泄漏任何内容,但您显然不想做出这些假设。
如果您没有任何保留属性或任何手动分配 ivar,那么只有这样,您才能使用 dealloc 方法。
希望有帮助。
我认为这在最新的iOS 5 +中是允许的,但以前您不应该向主视图控制器添加另一个视图控制器视图。这显然是误用,可能会导致问题。
视图控制器的概念是控制所有视图的人。视图控制器不应控制另一个视图控制器,除非它是容器视图控制器,例如 UINavigationController/UITabBarController。
所以请重新考虑设计。 为什么需要辅助视图控制器。为什么主视图控制器也不能管理辅助视图?
最后,每个视图控制器都应该包含 dealloc。
视图控制器添加到层次结构后需要从主视图控制器访问secondaryViewController
,则此时不应解除分配它。 如果在显示辅助控制器后不需要访问辅助控制器,则可以在此时解除分配它。
实际上,如果secondaryViewController
是一个 ivar,那么保留对它的引用可能是有意义的。 如果它是一个局部变量,并且您以后不访问它,则应对其进行 dealloc。