zoukankan      html  css  js  c++  java
  • snapkit更新约束崩溃的问题

    最近在使用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中相似问题

  • 相关阅读:
    SpringMVC参数校验
    SpringBoot2集成Activiti6
    spring boot与activiti集成实战 转
    使用国内阿里maven私服方法
    springboot2.04与activiti 6.0集成
    idea actiBPM插件生成png文件 (解决没有Diagrams或Designer选项问题)
    嵌入式Qt-4.8.6显示中文并且改变字体大小和应用自己制作的字体库
    基于Qt Assistant制作软件帮助文档
    推荐一本书,30天自制操作系统
    Qt5 UI信号、槽自动连接的控件重名大坑(UI生成的槽函数存在一个隐患,即控件重名。对很复杂的控件,不要在 designer 里做提升,而是等到程序启动后,再动态创建,可以避免很多问题)
  • 原文地址:https://www.cnblogs.com/shenyuiOS/p/9707995.html
Copyright © 2011-2022 走看看