【发布时间】:2011-04-06 12:09:12
【问题描述】:
我有一个 NIB 文件,其中一些类 (SomeClassView : UIView) 设置为 NIB 顶级视图的自定义类。 SomeClass 有 IBOutlets,我用它来连接我在 Interface Builder 中布置的 SomeClass 的子视图。
我像这样实例化 SomeClass:
- (id)initWithFrame:(CGRect)frame {
self = [[[[NSBundle mainBundle] loadNibNamed:@"SomeClassView" owner:nil options:nil] objectAtIndex:0] retain];
// "SomeClassView" is also the name of the nib
if (self != nil) {
self.frame = frame;
}
return self;
}
现在说我用 SubClassView 子类 SomeClass。我向 SubClassView 添加了一个名为 -(void)foo:
的方法- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self != nil) {
[self foo];
}
return self;
}
此时我收到一个运行时错误:* 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[SomeClassView foo:]: unrecognized selector sent to instance 0xAAAAAA”
似乎 SubClassView 的 initWithFrame 中的“self”仍设置为超级 SomeClassView。解决此问题的快速破解方法是更改 SubClassView initWithFrame 中的 isa 指针:
- (id)initWithFrame:(CGRect)frame {
Class prevClass = [self class];
self = [super initWithFrame:frame];
if (self != nil) {
isa = prevClass;
[self foo]; // works now
}
}
这不是一个理想的解决方法,因为我每次子类化时都必须更新 isa,或者甚至可能有不同的 init 方法我也必须更新。
1) 理想情况下,有没有一种简单的方法可以完全通过代码来解决这个问题?也许我设置 self = 加载的笔尖的方式?
2) 是否有一种替代架构更适合我正在尝试做的事情?一个示例是将所有者设置为 self,但是您必须手动设置所有属性/插座映射。
【问题讨论】:
标签: iphone objective-c cocoa-touch interface-builder nib