当我在NIB中创建一个对象时,该对象应该实现-initWithCoder:
。但是,我无法弄清楚实现这一点的常规模式。
我已经使用过此代码。
- (id) initWithCoder:(NSCoder *)aDecoder
{
if(self=[super initWithCoder:aDecoder])
{
// initialize my object.
}
return self;
}
但我必须为像这样的代码实例化的UIView制作相同的代码。
- (id) initWithCoder:(NSCoder *)aDecoder
{
if(self=[super initWithCoder:aDecoder])
{
// initialize my object.
}
return self;
}
- (id) initWithFrame:(CGRect)frame
{
if(self=[super initWithFrame:frame])
{
// initialie my obejct.
}
return self;
}
我觉得有些不对劲。有什么建议吗?
*在源代码中,初始化逻辑可以被提取到一个新方法中,但它不是一个点。
答案 0 :(得分:4)
使用awakeFromNib初始化从NIB文件创建的UIView。如果你想使它成为通用的,可以从NIB文件或以编程方式创建,可以创建一个类似configureObject的方法,并从指定的初始化程序(通常是initWithFrame :)和awakeFromNib中调用它。
- (void)configureObject {
// Do initialization here
}
- (id)initWithFrame:(CGRect)frame {
if(self = [super initWithFrame:frame])
{
[self configureObject];
}
return self;
}
- (void)awakeFromNib {
[self configureObject];
}
答案 1 :(得分:1)
除了雅克回答,这是解决这个问题的正确方法,你有一个逻辑错误。在initWithCoder
您设置self = [super initWithCoder:aDecoder];
,然后执行return [self init];
。在init
中,您再次通过self = [super init];
覆盖自我,可能会颠覆您在initWithCoder:
中所做的事情。再次在init
中,你有return [self init];
导致无限递归,直到堆栈溢出。
init方法的模式是这样的:
- (id) initWithFoo:(Bar *)baz {
if ((self = [super initWithFoo:baz])) {
// Do custom initialization.
}
return self;
}
或:
- (id) initWithFoo:(Bar *)baz {
if ((self = [super initWithSome:baz other:@"signature"])) {
// Do custom initialization.
}
return self;
}
此外,还有一点澄清:- (id) initWithCoder:(NSCoder *)aDecoder
在反序列化时被调用。在这种情况下,通过加载NIB / XIB完成反序列化。有一个对应的- (void)encodeWithCoder:(NSCoder *)encoder
。阅读Archives and Serialization Programming Guide,如果您想将对象存储在磁盘上或想通过网络传输它们,您可能会觉得很有用。
无论如何,对于NIB,一旦加载,就会为存储在NIB中的每个对象调用awakeFromNib
方法,并且它充当一种二级初始化器。
然后,有initWithFrame:
。这是指定的初始化程序,也是以编程方式创建UIView实例时调用的初始化程序。