我正在尝试在Swift中启动一个新的基于文档的Cocoa项目,并想创建一个子类NSWindowController(如在基于文档的应用程序的Apple指南中所建议的那样)。在ObjC中,您将创建一个NSWindowController子类的实例来发送initWithWindowNibName:消息,并通过调用superclasses方法相应地实现了该消息。
NSWindowController
initWithWindowNibName:
在斯威夫特init(windowNibName)仅作为一种方便的初始化,指定初始化的NSWindowController就是init(window)这显然想让我在一个窗口中通过。
init(windowNibName)
init(window)
我不能super.init(windowNibName)从我的子类中调用,因为它不是指定的初始化器,所以显然我必须实现convenience init(windowNibName),而后者又需要调用self.init(window)。但是,如果我只有nib文件,该如何访问nib文件的窗口以发送给该初始化程序?
super.init(windowNibName)
convenience init(windowNibName)
self.init(window)
您需要覆盖NSWindowController(init(),init(window)和init(coder))的所有三个指定的初始化器,或者都不重写它们,在这种情况下,您的子类将自动继承,init(windowNibName)而所有其他便捷的初始化器都将覆盖,您将能够使用超类的便捷的初始化器来构造它:
init()
init(coder)
// this overrides none of designated initializers class MyWindowController: NSWindowController { override func windowDidLoad() { super.windowDidLoad() } } // this one overrides all of them // // Awkwardly enough, I see only two initializers // when viewing `NSWindowController` source from Xcode, // but I have to also override `init()` to make these rules apply. // Seems like a bug. class MyWindowController: NSWindowController { init() { super.init() } init(window: NSWindow!) { super.init(window: window) } init(coder: NSCoder!) { super.init(coder: coder) } override func windowDidLoad() { super.windowDidLoad() } } // this will work with either of the above let mwc: MyWindowController! = MyWindowController(windowNibName: "MyWindow")
语言指南中的“初始化/自动初始化继承”对此进行了介绍:
但是,如果满足某些条件,则会自动继承超类初始化器。实际上,这意味着您不需要在许多常见情况下编写初始化程序覆盖,并且可以在安全的情况下以最小的努力继承超类初始化程序。 假设为子类中引入的任何新属性提供默认值,则适用以下两个规则: 规则1 如果子类没有定义任何指定的初始化器,它将自动继承其所有超类指定的初始化器。 规则2 如果您的子类提供了其所有超类指定的初始值设定项的实现(通过按规则1继承它们,或通过提供自定义实现作为其定义的一部分),则它会自动继承所有超类的便利初始值设定项。
但是,如果满足某些条件,则会自动继承超类初始化器。实际上,这意味着您不需要在许多常见情况下编写初始化程序覆盖,并且可以在安全的情况下以最小的努力继承超类初始化程序。
假设为子类中引入的任何新属性提供默认值,则适用以下两个规则:
规则1 如果子类没有定义任何指定的初始化器,它将自动继承其所有超类指定的初始化器。
规则2 如果您的子类提供了其所有超类指定的初始值设定项的实现(通过按规则1继承它们,或通过提供自定义实现作为其定义的一部分),则它会自动继承所有超类的便利初始值设定项。