带有编码器的 UIView 初始化导致递归

Posted

技术标签:

【中文标题】带有编码器的 UIView 初始化导致递归【英文标题】:UIView init with coder causes a recursion 【发布时间】:2015-11-29 11:50:48 【问题描述】:

我正在尝试将我准备好的位于 xib 文件中的 UIView 嵌入到情节提要中。

到目前为止我所做的是:

class TestUIView : UIView 
    @IBOutlet weak private var firstButton: UIButton!
    @IBOutlet weak private var secondButton: UIButton!

    // MARK - Lifetime

    required init?(coder aDecoder: NSCoder) 
        super.init(coder: aDecoder)

        let view = NSBundle.mainBundle().loadNibNamed("TestUIView", owner: self, options: nil).first as! TestUIView

        self.addSubview(view)
    

但由于某种原因,我得到了错误的访问内存异常。 通过查看堆栈跟踪,我看到一大堆对 initWithCoder 的调用 http://i.stack.imgur.com/iH6Am.png 我不确定为什么 NSBundle.mainBundle().loadNibNamed 会导致这种情况,有什么想法吗?

【问题讨论】:

推测 nib 文件包含一个 TestUIView 的实例,所以当loadNibNames 加载 nib 时,它会通过调用 init(coder) 实例化一个 TestUIView 实例来加载 nib 等等直到递归导致堆栈爆炸。为什么要在init(coder) 中加载笔尖? 【参考方案1】:

原来我做错的是我准备 .xib 文件的方式,我设置了 View 本身,而不是文件所有者到 TestUIView 类。 更改文件所有者(并重置约束)后,一切正常。

【讨论】:

将您的答案标记为已解决,以便对其他人有所帮助:)【参考方案2】:

对于未来的寻求者......

简介:当您不小心在 ContentView 的身份检查器中设置自定义视图类时,会发生required init?(coder aDecoder: NSCoder) 的递归调用。

当编译器尝试加载您的 Nib 文件(所有者视图)时,它首先需要启动您的 ContentView(参见下图)并且如果您错误地为您的 ContentView 或其任何一个设置了自定义类subviews,它会经历另一个 Nib 加载过程并陷入递归无限循环。

要以正确的方式做到这一点,您应该只为占位符部分的视图设置自定义视图类。请看下图中的1和2。

在这张图片中,我定义了一个名为 CardView 的自定义类。

【讨论】:

【参考方案3】:

您刚刚定义了构建包含TestUIViewTestUIView 的方法,该TestUIView 包含一个TestUIView...

你不必打电话

let view = NSBundle.mainBundle().loadNibNamed("TestUIView", owner: self, options: nil).first as! TestUIView

来自

init?(coder aDecoder: NSCoder)

这样你就创建了一个无限循环,因为loadNibNamed 会自动调用init?(coder aDecoder: NSCoder)

只需删除这些行

let view = NSBundle.mainBundle().loadNibNamed("TestUIView", owner: self, options: nil).first as! TestUIView
self.addSubview(view)

【讨论】:

但是,我如何将笔尖连接到类?删除这些课程,我的网点未设置。 顺便说一句,这是我得到这个想法的地方:iphonedev.tv/blog/2014/12/15/…

以上是关于带有编码器的 UIView 初始化导致递归的主要内容,如果未能解决你的问题,请参考以下文章

Objective C - 带有动画的自定义 UIView 类初始化

带有选项的 UIView drawRect 方法

带有 UIView 子类的惰性属性

在更改其嵌套的 UILabel 时移动 UIView 会导致视图跳回初始位置

如何将值从 XIB 传递到 UIView 初始化程序?

带有类参数的 std::thread 初始化导致类对象被多次复制