【问题标题】:Within a view controller, is it necessary to call removeFromSuperview on subviews during viewDidUnload?在视图控制器中,是否需要在 viewDidUnload 期间对子视图调用 removeFromSuperview?
【发布时间】:2011-06-10 09:06:19
【问题描述】:

许多人说,在视图控制器的viewDidUnload 方法中,您必须通过调用removeFromSuperview 方法来删​​除子视图。例如,Three20 会这样做:

- (void)viewDidUnload {
  [super viewDidUnload];
  ... snipped ...
  [_tableBannerView removeFromSuperview];
  TT_RELEASE_SAFELY(_tableBannerView);
  [_tableOverlayView removeFromSuperview];
  TT_RELEASE_SAFELY(_tableOverlayView);
  ... snipped ...
}

我理解这种信念背后的原因:如果你在loadView 中调用[self.view addSubview:_aView],你应该在viewDidUnload 中调用[_aView removeFromSuperview]。问题是,这似乎没有必要。当视图控制器的视图被释放时,它的 dealloc 方法会自动释放它的所有子视图。我的测试代码显示子视图在其父视图被释放时自动被释放:

@interface TestView : UIView
@end

@implementation TestView
- (id)retain {
    NSLog(@"view retain");
    return [super retain];
}
- (void)release {
    NSLog(@"view release");
    [super release];
}
- (id)init {
    NSLog(@"view init");
    return (self = [super init]);
}
- (void)dealloc {
    NSLog(@"view dealloc");
    [super dealloc];
}
@end

@interface TestViewController : UINavigationController
@end

@implementation TestViewController
- (void)loadView {
    NSLog(@"viewController loadView");
    [super loadView];
    [self.view addSubview:[[TestView new] autorelease]];
}
- (void)viewDidUnload {
    NSLog(@"viewController viewDidUnload");
    [super viewDidUnload];
}
- (void)viewDidAppear:(BOOL)animated {
    NSLog(@"viewDidAppear");
    [super viewDidAppear:animated];
    [self dismissModalViewControllerAnimated:YES];
}
- (void)dealloc {
    NSLog(@"viewController dealloc");
    [super dealloc];
}
@end

以上代码产生以下输出:

viewController loadView
view init
view retain
view release
viewDidAppear
viewController dealloc
view release
view dealloc

如你所见,当视图控制器的主视图被释放时,它的子视图也被释放。

此外,iOS 开发人员库 [状态](http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/BasicViewControllers/BasicViewControllers.html#//apple_ref/doc/uid/TP40007457-CH101- SW4 ): “在内存不足的情况下,如果当前未使用该视图,则默认 UIViewController 行为是释放存储在视图属性中的视图对象。”另外:“如果您使用声明的属性来存储对视图的引用,并且该属性使用保留语义,则为其分配 nil 值就足以释放视图。”

那么,如果释放一个视图会自动释放它的子视图,那么在viewDidUnload期间是否真的需要调用removeFromSuperview

【问题讨论】:

    标签: objective-c cocoa-touch uiviewcontroller


    【解决方案1】:

    不,没有必要,dealloc,正如你所说的那样,会为你做这件事:)(长帖,简短回答)。

    【讨论】:

      【解决方案2】:

      我发现它在我的项目中是必要的。我的 viewController 有一个主视图(就像他们一样),在这种情况下,它是使用 xib 定义的(不是以编程方式分配并添加为子视图)。此视图在视图控制器中有带有 IBOutlets 的子视图。如果在 viewDidUnload 上,我只是将 IBOutlet 属性设置为 nil ( self.mySubView = nil ),则不会调用该子视图上的 dealloc。如果我首先将它从它的超级视图(主视图)中删除,则调用 dealloc。

      【讨论】:

      • 您有任何示例代码来说明这一点吗?既然你提到了 XIB,把项目放到 Github 上会更有帮助。谢谢。
      猜你喜欢
      • 2011-06-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 1970-01-01
      • 2011-07-26
      • 2018-08-23
      相关资源
      最近更新 更多