使用编码器的UIView init会导致递归

时间:2015-11-29 11:50:48

标签: ios swift uiview

我正在尝试将我已准备好的UIView(位于xib文件中)嵌入到故事板中。

到目前为止,我所做的是:

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导致这个,有什么想法?

3 个答案:

答案 0 :(得分:9)

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

答案 1 :(得分:2)

对于未来的求职者。...

简述:当您在ContentView的身份检查器中意外设置自定义视图类时,将进行required init?(coder aDecoder: NSCoder)的递归调用。

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

为此,您应该只为“占位符”部分中的视图设置自定义视图类。请参见下图1和2。

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

enter image description here

答案 2 :(得分:1)

您刚刚定义了构建TestUIView的方式,其中包含的TestUIView包含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)