子视图控制器设置TableView.delegate时意外发现nil崩溃问题求助
问题根因
- IBOutlet版本崩溃原因:将WalletViewController作为侧边栏子控制器初始化时,没有从对应的Storyboard/XIB加载,导致IBOutlet修饰的table属性为nil,对nil对象设置delegate、dataSource触发崩溃。设为初始控制器时系统会自动从Storyboard实例化控制器,IBOutlet正常赋值,所以运行正常。
- 纯代码addSubview版本table不显示原因:没有给手动创建的table设置frame或自动布局约束,table默认尺寸为0,因此不可见。
修复方案
方案1:修复IBOutlet版本崩溃
- 实例化WalletViewController时必须从对应Storyboard加载,不要直接调用
WalletViewController()初始化,示例代码:
// 替换为你实际的Storyboard名称、控制器对应的Storyboard ID let storyboard = UIStoryboard(name: "Main", bundle: nil) guard let walletVC = storyboard.instantiateViewController(withIdentifier: "WalletViewController") as? WalletViewController else { return } // 再将walletVC添加到侧边栏的控制器层级中
- 可选防护:在viewDidLoad中添加判空逻辑,避免异常崩溃:
override func viewDidLoad() { super.viewDidLoad() guard let table = table else { print("table未正常加载,请检查控制器初始化逻辑") return } table.delegate = self table.dataSource = self table.register(UITableViewCell.self, forCellReuseIdentifier: "cell") // 剩余原有逻辑不变 }
方案2:修复纯代码版本table不显示
在viewDidLoad中给table添加尺寸约束,推荐用自动布局适配不同屏幕:
override func viewDidLoad() { super.viewDidLoad() view.addSubview(table) table.delegate = self table.dataSource = self table.register(UITableViewCell.self, forCellReuseIdentifier: "cell") // 新增自动布局代码 table.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ table.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), table.leadingAnchor.constraint(equalTo: view.leadingAnchor), table.trailingAnchor.constraint(equalTo: view.trailingAnchor), table.bottomAnchor.constraint(equalTo: button.topAnchor, constant: -20) ]) // 剩余原有逻辑不变 }
额外优化建议:你当前按钮的frame是写死的y: 800,在小屏设备上会超出可视区域,建议也改为自动布局适配。
内容的提问来源于stack exchange,提问作者Charles Morgan
相关产品推荐
相关产品推荐

