initWithFrame 未调用,但 awakeFromNib 是

Posted

技术标签:

【中文标题】initWithFrame 未调用,但 awakeFromNib 是【英文标题】:initWithFrame not called, but awakeFromNib is 【发布时间】:2009-01-11 19:56:57 【问题描述】:

我正在尝试继承 NSOutlineView。这是我的代码:

OutlineViewSublcass.h:

#import <Cocoa/Cocoa.h>

@interface OutlineViewSubclass : NSOutlineView 



@end

OutlineViewSubclass.m:

#import "OutlineViewSubclass.h"

@implementation OutlineViewSubclass

- (id)initWithFrame:(NSRect)frame

    self = [super initWithFrame:frame];
    printf("debug A\n");
    return self;


- (void)awakeFromNib

    printf("debug B\n");


@end

调试输出为:

debug B

为什么不调用(id)initWithFrame:(NSRect)frame

【问题讨论】:

【参考方案1】:

Cocoa 控件实现 NSCoding 协议以从 nib 取消归档。不是使用 initWithFrame: 初始化对象然后设置属性,而是 initWithCoder: 方法负责在使用 Interface Builder 配置的序列化属性加载控件时设置控件。这与使用 NSCoding 序列化任何对象的方式几乎相同。

如果你把一个自定义的 NSView 子类放在一个不实现 NSCoding 的 nib 中,这会有点不同,在这种情况下会调用 initWithFrame:。在这两种情况下,awakeFromNib 都会在对象加载后被调用,通常是在子类中执行额外初始化的好地方。

【讨论】:

(我指的是第二段)为什么当他在没有实现 NSCoder 的情况下子类化“NSOutlineView”时他没有在 initWithFrame: ("debug A") 上得到回调?【参考方案2】:

Apple 官方对此的回答是 Creating a Custom View。

在 Interface Builder 中创建的视图实例在加载其 nib 文件时不要调用 initWithFrame:,这通常会导致混淆。请记住,Interface Builder 在保存 nib 文件时会归档对象,因此视图实例已经被创建并且 initWithFrame: 已经被调用。

awakeFromNib 方法提供了一个机会,可以在由于加载 nib 文件而创建视图时提供视图的初始化。加载包含视图对象的 nib 文件时,当所有对象都已取消归档时,每个视图实例都会收到一条 awakeFromNib 消息。这为对象提供了一个机会来初始化未在 Interface Builder 中与对象一起归档的任何属性。

【讨论】:

链接出来很有帮助;有关更深入的讨论,请参阅Allocating the View 部分

以上是关于initWithFrame 未调用,但 awakeFromNib 是的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式加载 nib2 时,来自 nib1 的 awakeFromNib 被调用

Unity - 脚本的 Awake() 是不是在其他脚本的 Start() 之前运行?

在 Unity 中,是在游戏开始之前还是在场景开始之前调用 Awake()?

脚本生命周期

如何在 FLTK 库中使用 Fl::awake

unity 中函数调用的顺序