Objective-C老项目崩溃求助:添加子视图触发视图控制器报错
解决「Application tried to present modally a view controller that has a parent view controller」崩溃问题
问题根源分析
从报错和提供的代码来看,崩溃由两个核心问题导致:
- 控制器未正确初始化:
loadStartViewController中仅调用alloc创建StartViewController实例,未执行init(或对应初始化方法),导致控制器内部状态异常。 - 子控制器添加方式不规范:直接将子控制器的view添加到父视图,未通过iOS官方的控制器容器API建立父子关系,触发系统对控制器父节点状态的校验报错。
修复步骤
1. 修正控制器初始化逻辑
修改loadStartViewController方法,确保完成完整的初始化流程:
- (UIViewController*) loadStartViewController { // 基础初始化,若使用xib/storyboard需对应替换 StartViewController *viewController = [[StartViewController alloc] init]; // 若使用xib,替换为: // StartViewController *viewController = [[StartViewController alloc] initWithNibName:@"StartViewController" bundle:nil]; // 若使用storyboard,替换为: // UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; // StartViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"StartViewController"]; return viewController; }
2. 规范子控制器添加流程
修改viewDidLoad中的代码,遵循iOS控制器容器的生命周期管理规范:
- (void)viewDidLoad { [super viewDidLoad]; // 确保调用父类方法,老项目常遗漏 activeViewController = [self loadStartViewController]; // 建立父子控制器关系并添加视图 [self addChildViewController:activeViewController]; // 设置子视图尺寸适配父视图 activeViewController.view.frame = self.view.bounds; [self.view addSubview:activeViewController.view]; [activeViewController didMoveToParentViewController:self]; // 移除手动调用的viewDidAppear,系统会自动触发生命周期方法 // [activeViewController viewDidAppear:NO]; }
修复说明
- 仅
alloc不init会导致控制器的视图、属性等未完成初始化,后续操作会触发不可预测的崩溃。 - iOS要求子控制器必须通过
addChildViewController明确建立父子关系,直接添加view会让系统误判控制器的父节点状态,引发模态跳转相关的报错。 - 手动调用
viewDidAppear会打乱控制器的生命周期流程,规范添加后系统会自动执行对应生命周期方法。
内容的提问来源于stack exchange,提问作者JustMeShortie
相关产品推荐
相关产品推荐

