0

我正在用+(BOOL)loadNibNamed:owner:更标准的方法替换我们的 macOS 应用程序中不推荐使用的方法,initWithWindowNib并遇到了 Apple 指南关于Mac 的基于文档的应用程序编程指南。有一段特别引起了我的注意:An NSWindowController Subclass Manages Nib Files

对于记录,它说:

一个NSWindowController对象期望被告知要加载哪个 nib 文件(通过它的 initWithWindowNib... 方法),因为它是所有窗口控制器默认行为的通用实现。但是,当您编写 的子类时NSWindowController,该子类几乎总是旨在控制包含在特定 nib 文件中的用户界面,并且您的子类不适用于不同的 nib 文件。因此,子类的实例化器必须告诉它要加载哪个 nib 文件是不方便且容易出错的。

这个问题是通过覆盖方法来解决的,以使用正确的 nib nameinit调用超类的initWithWindowNibName:方法。然后实例化器只需使用init,并且控制器具有正确的 nib 文件。您还可以覆盖initWithWindowNib...记录错误的方法,如图 2-4 所示,因为任何实例化器都不应该尝试告诉您的子类使用哪个 nib 文件。NSWindowController任何设计为使用特定 nib 文件的子类使用此技术是一个好主意。仅当您仅扩展 NSWindowController子类中的基本功能并且没有将该功能绑定到任何特定的 nib 文件时,您才应该这样做。

图 2-4 加载特定于控制器的 nib 文件

很合理,我们试试看。


注意:有一个与同一文档部分相关的问题,但它有一个不同的问题,提出了一个不同的问题并且没有使用现代 Objective-C 语法。


我的 MainWindowDelegate.h 现在有:

- (instancetype)init NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithWindow:(nullable NSWindow *)window NS_UNAVAILABLE;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
- (instancetype)initWithWindowNibName:(NSNibName)windowNibName NS_UNAVAILABLE;
- (instancetype)initWithWindowNibName:(NSNibName)windowNibName owner:(id)owner NS_UNAVAILABLE;
- (instancetype)initWithWindowNibPath:(NSString *)windowNibPath owner:(id)owner NS_UNAVAILABLE;

MainWindowDelegate.m 现在有:

- (instancetype)init {

    self = [super initWithWindowNibName:@"MainWindowWin"];
    if (self) {
        // Initialization code here.

    }

    return self;
}

唯一可用的初始化程序AppDelegate是正确的init(如果我尝试使用,initWithWindowNibName那么我得到错误'initWithWindowNibName:' is unavailable)。到目前为止一切都很好,而且效果很好。

但现在我有一堆警告......

对于- (instancetype)init {线

指定的初始化程序缺少对超类的指定初始化程序的“超级”调用

对于self = [super initWithWindowNibName:@"MainWindowWin"];线

指定初始化程序调用了非指定初始化程序


如果这是建议的 Apple 子类化 NSWindowController 的方法,为什么会出现所有这些警告?我错过了重点吗?如何修复警告并仅维护init初始化程序的可用性?

4

0 回答 0