在继承NSView时,Xcode会要求实现init(coder:)初始化:
class ScreenshotOverlayView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
}
提示信息为:
'required' initializer 'init(coder:)' must be provided by subclass of 'NSView'
为什么会有这个报错提示呢?
这是因为,如果不自定义init()构造器,系统不会要求提供init(coder:):
class ScreenshotOverlayView: NSView {
// 无内容,无报错
}
因为init()构造器会自动继承。
当我们写了自定义的初始化器时,这个类就可能被NSCoding解码,Swift要求显式实现init?(coder:)。
这是出于“完整初始化覆盖链”的考虑:
子类自定义了初始化器,就必须显式地实现所有基类的 required 初始化器。
这是Swift的初始化规则,当子类添加自定义初始化器时,有责任保证所有required init都被实现。
即使代码中不会使用init(coder:),只要是父类标注了required,就不能忽略它。
因此,必须实现init(coder:)初始化器:
class ScreenshotOverlayView: NSView {
override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
}
// 如果没有这句,编译报错
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
init?(coder:)是什么?
它是用于 从 Interface Builder(如 Storyboard 或 XIB)中加载视图对象时的初始化方法。
required init?(coder: NSCoder)
如果使用 XIB 或 Storyboard 创建视图/窗口并加载,它会调用这个方法来「解码」视图;
它等价于 iOS 的 required init?(coder:),这个方法是 Apple 的 UI 框架强制实现的。
因为我们明确不会通过 Storyboard/XIB 使用这个类,所以就可以使用fatalError抛出错误:
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
相关文章
1、macOS和iOS界面设计文件.xib:https://fangjunyu.com/2025/06/30/macos%e5%92%8cios%e7%95%8c%e9%9d%a2%e8%ae%be%e8%ae%a1%e6%96%87%e4%bb%b6-xib/
2、Swift抛出致命错误的fatalError调试工具:https://fangjunyu.com/2025/03/29/swift%e6%8a%9b%e5%87%ba%e8%87%b4%e5%91%bd%e9%94%99%e8%af%af%e7%9a%84fatalerror%e8%b0%83%e8%af%95%e5%b7%a5%e5%85%b7/
3、从错误到解决:Swift required构造函数逐步解析:https://fangjunyu.com/2024/10/13/%e4%bb%8e%e9%94%99%e8%af%af%e5%88%b0%e8%a7%a3%e5%86%b3%ef%bc%9aswift-required%e6%9e%84%e9%80%a0%e5%87%bd%e6%95%b0%e9%80%90%e6%ad%a5%e8%a7%a3%e6%9e%90/