【问题标题】:Endless recursive calls to initWithCoder when instantiating xib in storyboard在情节提要中实例化 xib 时对 initWithCoder 的无休止的递归调用
【发布时间】:2012-05-14 09:26:05
【问题描述】:

为了在整个应用程序(基于故事板)中重用某个子视图,我决定将子视图构建为 nib,然后将其加载。为此,我做了以下工作:

我有一个 UIView 子类,我们可以称之为 Widget。我创建了一个相应的 xib 文件,将 File owner 属性设置为我的新子类,连接 IBOutlets。

然后,在我的故事板中,我在视图控制器中有一个 uiview,我将它的类设置为我创建的 Widget 类。

在小部件类中,我重写了 initWithCoder,并在其中加载 nib,如下所示:

-(id)initWithCoder:(NSCoder *)aDecoder{
    if ((self = [super initWithCoder:aDecoder])){
        [self addSubview:[[[NSBundle mainBundle] loadNibNamed:@"Widget" owner:self options:nil] objectAtIndex:0]];
    }
    return self;
}

此时应用程序会崩溃,并且在此处设置断点表明 initWithCoder 被一遍又一遍地调用。

在这种情况下,我似乎混合了两种使用笔尖的方法,但我不清楚我哪里出错了。如有必要,我可以抛出堆栈跟踪,但它基本上是对同一函数的无休止的嵌套调用。

【问题讨论】:

    标签: ios storyboard nib


    【解决方案1】:

    您是否碰巧在 .xib 文件中将视图的“自定义类”设置为“小部件”?

    这可以解释您所看到的行为,因为 initWithCoder: 是从 xib 加载的所有内容的初始化程序:

    1. 包含 Widget 对象的父视图是从 xib 加载的
    2. Widget 的 initWithCoder: 方法被调用,并尝试加载 Widget xib
    3. 小部件 xib 包含一个 UIView 和自定义 类“Widget”,所以再次初始化一个 Widget 对象 initWithCoder:

    如果确实如此,您所要做的就是在您的 Widget 的 xib 中删除 UIView 的“自定义类”条目。

    【讨论】:

    • 但如果您删除自定义类值,则无法使用其 IBOutlets 和 IBActions...
    • @nano 当然,您可以为视图使用自定义类;你只需要防止递归。
    • 在不从 xib 中删除“自定义类”的情况下防止递归的最佳方法是什么?
    • @Jaro 只需使用[[NSBundle mainBundle] loadNibNamed:@"YourNibFileNameWithoutSuffix" owner:self options:nil] 创建您的视图实例。这将创建您需要的 UIView 实例。您不能做的唯一一件事就是以编程方式创建视图类的实例,然后尝试在initWithCoder: 中加载它自己的 nib(因为这会导致创建视图类的另一个实例并且等等)。
    • @Andreas:这是我的错,我将“自定义类”设置为主“视图”而不是父视图控制器。在这里我们进行递归:) 经验教训..
    【解决方案2】:

    我有同样的问题。我的错误是在空文件的所有者类中。在 File's Owner 中自定义类必须不为空(Widget),并且根视图必须为空。

    IBActions 和 IBOutlets 都很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-10
      • 2019-11-12
      • 2013-03-03
      • 2019-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-31
      相关资源
      最近更新 更多