当前位置: 移动技术网 > IT编程>移动开发>IOS > snapkit更新约束崩溃的问题

snapkit更新约束崩溃的问题

2018年09月27日  | 移动技术网IT编程  | 我要评论

黄喉貂,蒙雷亚尔,六个月宝宝吐奶

最近在使用snapkit布局时,竟然发现更新约束会导致崩溃,为什么这样呢? 

        checkbutton.snp.makeconstraints { (make) in
            make.left.top.equaltosuperview()
            make.height.equalto(radiolistsubviewbuttonheight)
            make.width.equalto(self).multipliedby(0.5)
        }
        checkbutton.snp.updateconstraints { (make) in
                make.width.equalto(self).multipliedby(0.7)
        }

 

看起来完全没有问题,但是一运行就崩溃,崩溃位置在activeifneeded方法中:

    internal func activateifneeded(updatingexisting: bool = false) {
        guard let item = self.from.layoutconstraintitem else {
            print("warning: snapkit failed to get from item from constraint. activate will be a no-op.")
            return
        }
        let layoutconstraints = self.layoutconstraints

        if updatingexisting {
            var existinglayoutconstraints: [layoutconstraint] = []
            for constraint in item.constraints {
                existinglayoutconstraints += constraint.layoutconstraints
            }

            for layoutconstraint in layoutconstraints {
                let existinglayoutconstraint = existinglayoutconstraints.first { $0 == layoutconstraint }
                guard let updatelayoutconstraint = existinglayoutconstraint else {
                    fatalerror("updated constraint could not find existing matching constraint to update: \(layoutconstraint)")
                }

                let updatelayoutattribute = (updatelayoutconstraint.secondattribute == .notanattribute) ? updatelayoutconstraint.firstattribute : updatelayoutconstraint.secondattribute
                updatelayoutconstraint.constant = self.constant.constraintconstanttargetvaluefor(layoutattribute: updatelayoutattribute)
            }
        } else {
            nslayoutconstraint.activate(layoutconstraints)
            item.add(constraints: [self])
        }
    }

 

fatalerror信息提示找不到因存在的constraint来更新,输出existinglayoutconstraints不为nil,输出existinglayoutconstraint却为nil,很奇怪。

点击进入first方法,发现是取第一个满足谓词条件的值,而不是简单的取第一个值:

    /// returns the first element of the sequence that satisfies the given
    /// predicate.
    ///
    /// the following example uses the `first(where:)` method to find the first
    /// negative number in an array of integers:
    ///
    ///     let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
    ///     if let firstnegative = numbers.first(where: { $0 < 0 }) {
    ///         print("the first negative number is \(firstnegative).")
    ///     }
    ///     // prints "the first negative number is -2."
    ///
    /// - parameter predicate: a closure that takes an element of the sequence as
    ///   its argument and returns a boolean value indicating whether the
    ///   element is a match.
    /// - returns: the first element of the sequence that satisfies `predicate`,
    ///   or `nil` if there is no element that satisfies `predicate`.
    ///
    /// - complexity: o(*n*), where *n* is the length of the sequence.
    public func first(where predicate: (element) throws -> bool) rethrows -> element?

在此处谓词条件为 $0 == layoutconstraint ,进入layoutconstraint类中,发现==运算符已被重载:

internal func ==(lhs: layoutconstraint, rhs: layoutconstraint) -> bool {
    guard lhs.firstitem === rhs.firstitem &&
          lhs.seconditem === rhs.seconditem &&
          lhs.firstattribute == rhs.firstattribute &&
          lhs.secondattribute == rhs.secondattribute &&
          lhs.relation == rhs.relation &&
          lhs.priority == rhs.priority &&
          lhs.multiplier == rhs.multiplier else {
        return false
    }
    return true
}

在判断相等时,竟然还判断了multiplier,本例中更新约束前后multiplier不相等,所以找不到对应的约束。

 

解决方法:

要想修改multiplier,不能使用update,要使用remake

snapkit issue中相似问题

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网