连接IBOutlet后NIB加载失败报NSUnknownKeyException异常如何解决
根因说明与最终解决方法
最终更新: 问题根因已定位,连接outlet时File's Owner被设置为AttributesPanel,导致连接绑定到了该抽象实体而非实际的Swift UIView子类。后续将File's Owner改回NSObject后触发错误,因为系统期望NSObject持有这些outlet。
最终解决方法:删除IB中所有已有的连接,将File's Owner设为NSObject后重新连接,所有连线直接绑定到nib对应的类即可。
你可能以为编译阶段会有合理性校验提醒这类问题,但实际并没有。
问题背景
更新: 最初认为是outlet连接导致问题,但断开所有outlet连接后依然会崩溃。
采用Nib方案开发,App内有大量小型调色板/面板需要在运行时动态展示和移除。第一个面板加载正常,但连接好outlet后触发如下崩溃错误:
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<NSObject 0x6000031f2a20> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key clearRenderAreaButton.'
相关代码
面板展示代码
func openAlert() { self.view.addSubview(attributesPanel) NSLayoutConstraint.activate([ attributesPanel.leadingAnchor.constraint(equalTo: drawingRenderPanel.leadingAnchor, constant: 100), attributesPanel.bottomAnchor.constraint(equalTo: drawingRenderPanel.bottomAnchor, constant: -100), attributesPanel.widthAnchor.constraint(equalToConstant: 650), attributesPanel.heightAnchor.constraint(equalToConstant: 160) ]) }
面板实例化逻辑
private lazy var attributesPanel: AttributesPanel = { let view = AttributesPanel.instanceFromNib() view.translatesAutoresizingMaskIntoConstraints = false return view }()
AttributesPanel类实现
import UIKit class AttributesPanel: UIView { class func instanceFromNib() -> AttributesPanel { let view = UINib(nibName: "AttributesPanel", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! AttributesPanel return view } @IBOutlet weak var useStrokeSwitch: UISwitch? @IBOutlet weak var strokeWeightLabel: UILabel? @IBOutlet weak var strokeHevValField: UILabel? @IBOutlet weak var strokeColorWellView: UIView? @IBOutlet weak var strokeUseOpacitySwitch: UISwitch? @IBOutlet weak var strokeOpacityField: UILabel? @IBOutlet weak var useFillSwitch: UISwitch? @IBOutlet weak var fillColorWellView: UIView? @IBOutlet weak var fillHexValField: UILabel? @IBOutlet weak var fillUseOpacitySwitch: UISwitch? @IBOutlet weak var fillOpacityField: UILabel? @IBOutlet weak var currentRenderPathField: UILabel? @IBOutlet weak var setRenderAreaButton: UIButton? @IBOutlet weak var clearRenderAreaButton: UIButton? @IBOutlet weak var renderCurrentPathButton: UIButton? }
排查过程
- 所有outlet在IB中均已完成连接,未连接outlet时功能运行正常,约束生效,NIB可正常展示
- 排查File's Owner绑定配置,修改配置后崩溃问题仍存在
- 断点调试发现NIB加载节点返回nil,排除NIB名称不匹配问题(未连接outlet时可正常加载)
内容的提问来源于stack exchange,提问作者Dan Donaldson
相关产品推荐
相关产品推荐

