经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » iOS » 查看文章
snapkit更新约束崩溃的问题
来源:cnblogs  作者:小雨37  时间:2018/9/27 16:40:31  对本文有异议

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

  1. checkButton.snp.makeConstraints { (make) in
  2. make.left.top.equalToSuperview()
  3. make.height.equalTo(radioListSubviewButtonHeight)
  4. make.width.equalTo(self).multipliedBy(0.5)
  5. }
  6. checkButton.snp.updateConstraints { (make) in
  7. make.width.equalTo(self).multipliedBy(0.7)
  8. }

 

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

  1. internal func activateIfNeeded(updatingExisting: Bool = false) {
  2. guard let item = self.from.layoutConstraintItem else {
  3. print("WARNING: SnapKit failed to get from item from constraint. Activate will be a no-op.")
  4. return
  5. }
  6. let layoutConstraints = self.layoutConstraints
  7. if updatingExisting {
  8. var existingLayoutConstraints: [LayoutConstraint] = []
  9. for constraint in item.constraints {
  10. existingLayoutConstraints += constraint.layoutConstraints
  11. }
  12. for layoutConstraint in layoutConstraints {
  13. let existingLayoutConstraint = existingLayoutConstraints.first { $0 == layoutConstraint }
  14. guard let updateLayoutConstraint = existingLayoutConstraint else {
  15. fatalError("Updated constraint could not find existing matching constraint to update: \(layoutConstraint)")
  16. }
  17. let updateLayoutAttribute = (updateLayoutConstraint.secondAttribute == .notAnAttribute) ? updateLayoutConstraint.firstAttribute : updateLayoutConstraint.secondAttribute
  18. updateLayoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: updateLayoutAttribute)
  19. }
  20. } else {
  21. NSLayoutConstraint.activate(layoutConstraints)
  22. item.add(constraints: [self])
  23. }
  24. }

 

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

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

  1. /// Returns the first element of the sequence that satisfies the given
  2. /// predicate.
  3. ///
  4. /// The following example uses the `first(where:)` method to find the first
  5. /// negative number in an array of integers:
  6. ///
  7. /// let numbers = [3, 7, 4, -2, 9, -6, 10, 1]
  8. /// if let firstNegative = numbers.first(where: { $0 < 0 }) {
  9. /// print("The first negative number is \(firstNegative).")
  10. /// }
  11. /// // Prints "The first negative number is -2."
  12. ///
  13. /// - Parameter predicate: A closure that takes an element of the sequence as
  14. /// its argument and returns a Boolean value indicating whether the
  15. /// element is a match.
  16. /// - Returns: The first element of the sequence that satisfies `predicate`,
  17. /// or `nil` if there is no element that satisfies `predicate`.
  18. ///
  19. /// - Complexity: O(*n*), where *n* is the length of the sequence.
  20. public func first(where predicate: (Element) throws -> Bool) rethrows -> Element?

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

  1. internal func ==(lhs: LayoutConstraint, rhs: LayoutConstraint) -> Bool {
  2. guard lhs.firstItem === rhs.firstItem &&
  3. lhs.secondItem === rhs.secondItem &&
  4. lhs.firstAttribute == rhs.firstAttribute &&
  5. lhs.secondAttribute == rhs.secondAttribute &&
  6. lhs.relation == rhs.relation &&
  7. lhs.priority == rhs.priority &&
  8. lhs.multiplier == rhs.multiplier else {
  9. return false
  10. }
  11. return true
  12. }

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

 

解决方法:

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

snapkit issue中相似问题

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号