如何初始化从 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内部实现了TimePickerViewsetupSizes 【参考方案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 子类?继承问题的主要内容,如果未能解决你的问题,请参考以下文章

从xib初始化的UIView如何继承?

为UIView自定义Xib

UIView:从自定义 XIB 加载导致崩溃

从 XIB 加载自定义视图,如何使其响应自定义子类?

带有 Xib 文件的 UIView 的子类

对于直接从 Xib 加载的 UIView,何时应用 UIView 大小类?