You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将VCB的View添加到VCA未用addChildViewController,为何自动调用生命周期方法?是否必用?

iOS子视图控制器生命周期与容器控制器使用问题

现有两个ViewController,分别为VCA和VCB,我需要将VCB的View添加到VCA的View中作为子视图。但我未使用addChildViewController方法,而是直接调用[vca.view addSubview:vcb.view],却发现VCB的viewWillAppear、viewDidAppear方法被自动调用了。我想了解该现象的原因,同时想知道在添加其他ViewController的View作为子视图时,是否必须使用addChildViewController方法。

相关代码如下:

// ViewControllerA.m
- (void)showVCBView {
    ViewControllerB *vcb = [[ViewControllerB alloc] init];
    [self.view addSubview:vcb.view];
}

一、直接添加View触发VCB生命周期方法的原因

当你访问vcb.view时,系统会自动触发VCB的loadView或viewDidLoad完成视图加载。而当这个视图被添加到已经处于显示状态的父视图(VCA的view此时已经在屏幕上)时,UIKit内部会检测到视图的window属性从nil变为非nil,且父视图处于可见状态,就会自动触发它所属ViewController的viewWillAppear:和viewDidAppear:方法——这是UIKit内置的视图状态同步逻辑。

二、是否必须使用addChildViewController

不是语法上的“必须”,但强烈推荐严格遵循这个规范,核心原因有这些:

  • 生命周期不完整:如果不添加子控制器,VCB的viewWillDisappear:、viewDidDisappear:等后续生命周期方法不会自动触发(比如VCA的view被隐藏或移除时,VCB的对应方法不会执行),导致VCB无法正确处理视图消失后的逻辑(比如停止动画、释放资源)。
  • 内存风险:代码里vcb是局部变量,直接添加View后,VCB没有被VCA持有,会被提前释放,可能引发野指针崩溃。用addChildViewController会让VCA持有VCB,保证其生命周期和容器控制器同步。
  • 适配问题:UIKit的旋转、尺寸变化通知只会传递给当前ViewController层级内的控制器,未添加为子控制器的VCB收不到这些通知,容易出现布局错乱。
  • 符合设计逻辑:系统自带的容器控制器(比如UINavigationController、UITabBarController)都是通过这种方式管理子控制器的,遵循规范能避免很多隐性问题。

正确的子控制器添加流程应该是:

- (void)showVCBView {
    ViewControllerB *vcb = [[ViewControllerB alloc] init];
    [self addChildViewController:vcb];
    [self.view addSubview:vcb.view];
    // 按需设置子视图布局,比如frame或AutoLayout
    vcb.view.frame = self.view.bounds;
    [vcb didMoveToParentViewController:self];
}

移除时的对应流程:

- (void)removeVCBView {
    ViewControllerB *vcb = self.childViewControllers.firstObject;
    [vcb willMoveToParentViewController:nil];
    [vcb.view removeFromSuperview];
    [vcb removeFromParentViewController];
}

内容的提问来源于stack exchange,提问作者carol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:41:05