如何初始化从 xib 加载的 UIView 子类?继承问题
Posted
技术标签:
【中文标题】如何初始化从 xib 加载的 UIView 子类?继承问题【英文标题】:How to initialize UIView subclass that is load from xib? Problems with inheritance 【发布时间】:2016-03-09 11:45:29 【问题描述】:您好,我创建了 UIView 子类 MightyPickerView,它像这样从 xib 加载。
- (instancetype)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame];
if (self)
NSArray *arrayOfViews = [[NSBundle mainBundle] loadNibNamed:@"MightyPickerView" owner:self options:nil];
if ([arrayOfViews count] < 1)
return nil;
if (![[arrayOfViews objectAtIndex:0] isKindOfClass:[MightyPickerView class]])
return nil;
self = [arrayOfViews objectAtIndex:0];
return self;
到目前为止,这很好用,我在以前的许多项目中也使用过它,没有任何问题。但现在我想创建名为TimePickerView
的 MightyPickerView 的子类。
- (instancetype)initWithFrame:(CGRect)frame
self = [super initWithFrame:frame]; // here's the problem
if (self)
[self setupSizes];
return self;
当我运行应用程序时它崩溃了
[MightyPickerView setupSizes]: unrecognized selector sent to instance 0x137e53660
问题是这行self = [super initWithFrame:frame];
返回的是 MightyPickerView 而不是 TimePickerView。
我应该如何编写 MightyPickerView 的初始化器,以便它在需要时返回子类。
【问题讨论】:
你的 MightyPickerView.xib 中没有 TimePickerView 的出口吗? TimePickerView 不是 MightyPickerView 的属性。它是 MightyPickerView 的子类。 MightyPickerView 不应该对 TimePickerView 有任何了解。 而不是超级初始化。你可以试试 [[self alloc] init] 吗? 抱歉这个错误。为了简单起见,我用较短的类名更改了类名。我在错误消息中打错了字。所以我没有在TimePickerView
内部实现了TimePickerView
和setupSizes
是。
【参考方案1】:
你的所作所为毫无意义。你不应该滥用initWithFrame
来让你的视线转向并从笔尖加载自身。如果您想从 nib 加载 MightyPickerView,请从 nib 加载它,即有一些 other 类说 [[NSBundle mainBundle] loadNibNamed:@"MightyPickerView" owner:nil options:nil];
并拉出视图。要封装,也许可以使用类工厂方法。不要在init
中进行这种卑鄙的自我替换。它可能看起来很有效,但它总是错误的行为,现在它又回来咬你了。
【讨论】:
好的。这是一个很好的答案,因为我不知道这不是从 xib 创建视图的推荐方式。谢谢 这是真的,但改变它并不能解决他的根本问题,即从 nib 加载视图永远不会是正确的子类。 @dan 当然,如果这就是笔尖里的东西的话。 对,但他的问题是他想让一个子类使用与超类相同的 nib,但让视图作为子类的实例从 nib 出来。 @dan 好吧,如果这是他的问题,那么他就是疯了。如果他认为这会发生,他不知道什么是 nib(或者什么是实例,也许)。笔尖实例化。根据在笔尖中指定的类,它们就像在说[MyClass new]
(以及适当的初始化和可能的一些进一步配置)。您不能仅仅通过将 A 类称为子类 B 将其变成子类 B。多态性,您不知道吗?它必须从一开始就成为子类 B。以上是关于如何初始化从 xib 加载的 UIView 子类?继承问题的主要内容,如果未能解决你的问题,请参考以下文章