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() 之前运行?