UIView:除非首先调用no-op constraints(),否则addConstraint将失败并显示EXC_BAD_INSTRUCTION

时间:2014-10-15 05:13:48

标签: ios xcode swift autolayout

我的布局要求从模型中的(间接)数据更新乘数。简而言之,我可以删除约束并从中创建修改的约束。当我尝试通过addConstraint(...)再次添加约束时,我得到了名义上的EXC_BAD_INSTRUCTION错误。

奇怪的是,当我添加调试代码来检查现有约束时,问题就消失了。除了另一个iOS / Swift错误之外,是否有任何可能的解释?

我的代码看起来像这样:

    myView?.constraints() // crashes without this line, only works with it
    myView?.removeConstraint(self.myConstraint)
    self.myConstraint = myConstraint.withMultiplier(someModelDoubleValue / 14.0)
    myView?.addConstraint(self.myConstraint) // crashes here without first line

有没有其他人这样做过 - 这似乎是微不足道的,我无法想象它不会被测试。

请注意,withMultiplier方法只是我的功能灵感扩展方法,但它已经过测试,并且可以正常工作。但是,对于完整的披露,它看起来像这样:

extension NSLayoutConstraint {
    func withMultiplier(newMultiplier:CGFloat) -> NSLayoutConstraint {
        return NSLayoutConstraint(
            item: firstItem, attribute: firstAttribute,
            relatedBy: relation,
            toItem: secondItem, attribute: secondAttribute,
            multiplier: newMultiplier, constant: constant)
    }
}

1 个答案:

答案 0 :(得分:2)

我相信您的self.myConstraint是一个weak引用,其中包含"隐式解包的选项"喜欢:

@IBOutlet weak var myConstraint: NSLayoutConstraint!

它已在myView?.removeConstraint(self.myConstraint)解除分配。然后,在myConstraint.withMultiplier(myConstraintnil,这会导致错误。

如果是这样,只需省略weak或使用临时变量,如:

var constraint = self.myConstraint
myView?.removeConstraint(constraint)
constraint = constraint.withMultiplier(someModelDoubleValue / 14.0)
myView?.addConstraint(constraint)
self.myConstraint = constraint

为什么myView?.constraints()解决了这个问题?也就是说,constraints()返回带有NSArray ed的autorelease()。该数组具有对约束的强引用,并且存在于当前自动释放池中。