Xcode 13 beta 5报错UIViewController缺失初始trait collection如何解决
问题根因
这是Xcode 13搭载的iOS 15 SDK新增的运行时检查触发的崩溃,低版本iOS系统无此逻辑不会复现。从崩溃栈可以明确看到:UITableViewController在dealloc阶段访问了traitCollection属性,此时ViewController的初始化流程尚未走完,未生成初始trait集合,触发了Apple新增的断言校验抛出异常。
崩溃和你的初始化顺序直接相关:如果给dataProvider赋值的过程中,或是设置delegate的操作触发了任意self(UIViewController子类)的方法/属性访问(比如dataProvider的didSet钩子、delegate的立即回调),就会在父类init执行前触发UIKit逻辑,破坏UIViewController的初始化约定。
修复方案
按优先级可选以下方案:
- 调整初始化逻辑顺序,规避初始化阶段的风险操作
如果dataProvider是可变属性,严格遵循先执行父类初始化、再操作自身相关逻辑的规范:
init(dataProvider: DataProvider) { super.init(style: .plain) self.dataProvider = dataProvider dataProvider.delegate = self }
如果dataProvider是不可变let存储属性,无法调整赋值顺序,就把dataProvider.delegate = self的操作移到viewDidLoad中执行,避免初始化阶段触发和self相关的回调。
- 排查属性修饰符与隐藏逻辑
- 检查
DataProvider的delegate属性必须用weak修饰,禁止使用unowned或assign,避免野指针访问 - 检查
MyViewController所有属性的didSet/willSet钩子,确保初始化阶段没有触发View相关的更新逻辑 - 检查是否有自定义
deinit实现,移除所有访问UI属性(view、traitCollection、navigationItem等)的代码,iOS 15之后未完成初始化就释放的ViewController访问这些属性必然触发崩溃
临时调试方案
如果是Xcode Beta版本的UIKit本身bug导致的偶现崩溃,可以在项目的Other C Flags中添加编译参数临时禁用该断言:-DUIKIT_DISABLE_TRAIT_COLLECTION_INITIALIZATION_ASSERT=1,该参数仅可用于调试,禁止带入正式发布版本。
内容的提问来源于stack exchange,提问作者Aggressor
相关产品推荐
相关产品推荐

