我在我的
Cocoa项目中添加了一个自定义的NSWindowController子类,并将我的子类的一个实例添加到我的应用程序的nib中.我希望在加载nib时看到我对-initWithCoder:方法的覆盖,但事实并非如此.为了调试,我添加了一个常规的-init方法并在其上设置断点 – 当然,我在加载nib时点击了断点.
这实际上可以让一些事情变得更简单(例如设置windowNibName),但我不明白为什么Cocoa会以这种方式运行.我读过的所有文档都表明-initWithCoder:我应该重写的地方.为什么这个案子有什么不同?
解决方法
我假设在Interface Builder中实例化你的窗口控制器,你将一个通用的NSObject实例拖到nib文件,然后将你的自定义NSWindowController子类指定为对象的类,这是正确的吗?如果是这样,那么我认为它们的主要区别在于你正在处理实例化一个通用对象而不是IB调色板中包含的自定义对象.
大多数情况下,当您使用IB创建和配置对象时,在保存nib文件时,使用encodeWithCoder:方法对您在各种检查器中指定的设置进行编码.然后在应用程序中加载该nib文件时,使用initWithCoder:方法初始化这些对象.
但是,在该通用对象实例的情况下,Interface Builder不一定知道有关被实例化的对象的类的任何信息.由于您可以指定要实例化的任何类名,如果您指定IB没有通过调色板或框架加载的类,则无法使用NSCoding序列化该对象.所以我相信当你实例化这样的通用对象时,它会使用init而不是initWithCoder进行初始化:因为它不是使用encodeWithCoder保存的:首先保存nib文件.
我不知道这是否记录在任何地方,但我认为这就是为什么你会看到那里的差异.我也不认为它特定于NSWindowController,而是你会看到在IB中实例化为通用NSObject的任何对象都有相同的行为,无论具体的类如何.