尝试调用loadNibNamed时,IBDesignable崩溃EXC_BAD_ACCESS

时间:2016-02-24 01:08:09

标签: ios ibdesignable

我有一个名为DesignableControl的基类。我在自定义视图中使用它,以便我可以在故事板中看到它们。这是基类:

public class DesignableControl: UIControl {

    private var view: UIView!

    override public init(frame: CGRect) {
        super.init(frame: frame)
        configureViewForStoryboard()
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configureViewForStoryboard()
    }

    func configureViewForStoryboard() {
        if let nibView = NSBundle(forClass: self.dynamicType).loadNibNamed("\(self.dynamicType)", owner: self, options: nil).first as? UIView {
            view = nibView
        } else {
            Log("Error loading view for storyboard preview. Couldn't find view named \(self.dynamicType)")
            view = UIView()
        }
        view.frame = bounds
        view.autoresizingMask = [UIViewAutoresizing.FlexibleWidth, UIViewAutoresizing.FlexibleHeight]
        backgroundColor = .clearColor()
        addSubview(view)
    }
}

这是我的子类StackedButton

class StackedButton: DesignableControl {
    @IBOutlet weak var imageView: UIImageView!
    @IBOutlet weak var imageViewHeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var imageViewWidthConstraint: NSLayoutConstraint!
    @IBOutlet weak var label: UILabel!

    ...
}

上面的代码在我运行应用程序时运行并且看起来很好,但是,当我在故事板中查看它时,它会在EXC_BAD_ACCESS的以下行中使用DesignableControl崩溃Interface Builder进程(已损坏为了清楚起见):

func configureViewForStoryboard() {
    let bundle = NSBundle(forClass: self.dynamicType)
    print("bundle: \(bundle)")
    let nibArray = bundle.loadNibNamed("\(self.dynamicType)", owner: self, options: nil)
    print("nibArray: \(nibArray)") //<-- EXC_BAD_ACCESS

    ...
}

当我第一次编写此代码时,它曾经起作用,但似乎在最新版本的Xcode(本文中的7.2.1)中被破坏了。我做错了什么?

1 个答案:

答案 0 :(得分:0)

<强>更新

代码在运行时开始崩溃,因为视图没有正确设置。事实证明,堆栈溢出问题是一个红色的鲱鱼。某些@IBDesignable属性中的子类中存在一个错误,在设置之前访问@IBOutlets。这是根本问题。

在:

@IBInspectable var text: String? {
    get { return label.text }
    set { label.text = newValue }
}

后:

@IBInspectable var text: String? {
    get { return label?.text }
    set { label?.text = newValue }
}

原始答案:

Stack overflow™!!!

loadNibNamed()正在调用其中一个构造函数,它正在调用configureViewForStoryboard(),它正在调用一个构造函数,它正在调用configureViewForStoryboard()

我从configureViewForStoryboard()移除了对init?(coder aDecoder: NSCoder)的电话,现在似乎有效了。