NSView初始化:-init:与-awakeFromNib:的区别

7
我有一个简单的类MyView,它是从NSView继承而来,其中包含实例变量NSImage * image;。该类的功能是在视图上绘制图像。

然而,在-drawRect:函数中,如果image实例是在-init:函数中初始化的,那么它总是等于nil,如果是在-awakeFromNib:函数中初始化的,则不为nil。日志显示-init:-awakeFromNib:函数仅被调用一次。

默认情况下,-awakeFromNib:是否会重新初始化GUI组件?

1个回答

9

不,awakeFromNib没有默认实现。

你的问题在于你重写了错误的初始化方法。一个 NSView指定初始化器initWithFrame:。你的子类的普通 init 方法永远不会被调用,这就是为什么你的 image 实例变量没有指向任何东西的原因。

你可以在 awakeFromNib 或者 initWithFrame: 中初始化那个实例变量,两者都可以。前者在后者之后调用,它作为一个点提供,你可以在其中插入需要与你的 nib 中的其他对象(通过你的 IBOutlets)进行交互的初始化代码。


2
尽管在某些情况下,-initWithFrame根本没有被调用(https://dev59.com/xXRC5IYBdhLWcg3wCMc6)。 - jlstrecker
7
只有一种情况下,你自定义的子类 initWithFrame: 才不会被调用:当它继承自另一个存在于 IB Palette 中的 NSView 子类(例如 NSImageView),并且你通过更改身份检查器中的类来创建你自定义子类的实例。在这种情况下,AppKit 子类的 initWithFrame: 将被调用,并且你的自定义子类将在 awakeFromNib 之前得到 initWithCoder:。如果你在 IB 中使用“自定义视图”对象创建视图实例,则确实会调用你的视图的 initWithFrame: - jscs
1
我创建了一个_Custom View_,并在Identity Inspector中将我的NSView子类设置为其类。 我没有收到对initWithFrame:的调用; 尽管会调用awakeFromNib。 这是在macOS 10.14.1上,使用Xcode 10.1。 - legends2k
在与@legends2k所描述的类似情况下,我的NSView子类也没有收到对initWithFrame的调用;但它确实收到了对initWithCoder的调用。 - Jon Schneider

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接