SnapKit 约束创建过程

Posted huahuahu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SnapKit 约束创建过程相关的知识,希望对你有一定的参考价值。

技术分享图片?

创建ConstraintViewDSL

调用UIViewsnp 方法,生成一个ConstraintViewDSL
注意这个生成的ConstraintViewDSL持有UIView

创建ConstraintMaker

调用makeConstraints,调用ConstraintMaker对应的静态方法。
在方法的实现中,创建一个ConstraintMaker
注意这个ConstraintMaker,持有UIView

internal static func prepareConstraints(item: LayoutConstraintItem, closure: (_ make: ConstraintMaker) -> Void) -> [Constraint] {
    let maker = ConstraintMaker(item: item)
    closure(maker)
    var constraints: [Constraint] = []
    for description in maker.descriptions {
        guard let constraint = description.constraint else {
            continue
        }
        constraints.append(constraint)
    }
    return constraints
}

调用闭包中的方法,生成ConstraintMakerRelatable

在调用snp.left 等方法时,会调用makeExtendableWithAttributes()生成 ConstraintMakerExtendable 实例。

public var left: ConstraintMakerExtendable {
    return self.makeExtendableWithAttributes(.left)
}

makeExtendableWithAttributes() 方法中,会生成ConstraintDescription,并被加到ConstraintMaker的一个数组中。

internal func makeExtendableWithAttributes(_ attributes: ConstraintAttributes) -> ConstraintMakerExtendable {
    let description = ConstraintDescription(item: self.item, attributes: attributes)
    self.descriptions.append(description)
    return ConstraintMakerExtendable(description)
}

ConstraintMakerRelatable中,完善约束的属性信息

ConstraintMakerExtendableConstraintMakerRelatable的子类。
这两个类要提供的信息是哪个View的什么属性要和哪个View的什么属性产生联系

public class ConstraintMakerExtendable: ConstraintMakerRelatable {
    // 完善from 的属性信息
    public var left: ConstraintMakerExtendable {
        self.description.attributes += .left
        return self
    }
    ...
}

public class ConstraintMakerRelatable {
    internal func relatedTo(_ other: ConstraintRelatableTarget, relation: ConstraintRelation, file: String, line: UInt) -> ConstraintMakerEditable {
    ...
        let editable = ConstraintMakerEditable(self.description)
        editable.description.sourceLocation = (file, line)
        // 约束信息的目标对象
        editable.description.relation = relation
        editable.description.related = related
        editable.description.constant = constant
    }
}

ConstraintMakerFinalizable类中,完善约束细节

ConstraintMakerEditable->ConstraintMakerPriortizable->ConstraintMakerFinalizable
这三个类分别细化约束的具体数值、优先级、标签。

public class ConstraintMakerFinalizable {
    ...
    public var constraint: Constraint {
        return self.description.constraint!
    }
    ...
}

可以通过constraint方法,生成真实需要的约束。

内存问题

上面提到的类,都是生成约束过程中用到的,生成约束以后,就都销毁了。
生成的约束,被UIView持有,最终在内存中的,也只有Constraint这个属性以及它持有的其他属性。

Constraint 被 UIView 持有

技术分享图片?

可以看到Constraint被加在了一个Set中, 技术分享图片?

而这个Set是约束被加到UIView中时,第一次取Set时,被初始化的。

Constraint 持有 ConstraintItem

技术分享图片?

技术分享图片?

fromto属性

ConstraintItem 通过weak持有 UIView

public final class ConstraintItem {
    
    internal weak var target: AnyObject?
    internal let attributes: ConstraintAttributes
}

通过打印,也可以看到这一点。

(lldb) po blueView
<UIView: 0x7fe47bf998b0; frame = (0 0; 0 0); layer = <CALayer: 0x7fe47bf96fb0>>

(lldb) po blueView.constraintsa.first!.from.target
? Optional<AnyObject>
  - some : <UIView: 0x7fe47bf998b0; frame = (0 0; 0 0); layer = <CALayer: 0x7fe47bf96fb0>>

参考

以上是关于SnapKit 约束创建过程的主要内容,如果未能解决你的问题,请参考以下文章

自动布局 [Snapkit] 更改旋转约束

如何使用 SnapKit 在 iOS 中使用纵横比约束?

SnapKit 更新约束导致冲突

错误 swift2 约束 SnapKit

使用 SnapKit 对 UIView 进行约束但啥也不显示

UITableView HeaderView,FooterView 使用SnapKit布局导致约束异常