创建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 约束创建过程的更多相关文章

  1. Oracle 唯一 索引 约束 创建 删除

    http://www.blogjava.net/lukangping/articles/340683.html/*给创建bitmap index分配的内存空间参数,以加速建索引*/ show para ...

  2. mysql_pw 指令 数据库创建过程

    ------------------pw_db数据库创建过程各表创建指令-------------------------- create database pw_db; #创建一个数据库use pw ...

  3. ASP.NET Web API 控制器创建过程(二)

    ASP.NET Web API 控制器创建过程(二) 前言 本来这篇随笔应该是在上周就该写出来发布的,由于身体跟不上节奏感冒发烧有心无力,这种天气感冒发烧生不如死,也真正的体会到了什么叫病来如山倒,病 ...

  4. ASP.NET Web API 控制器创建过程(一)

    ASP.NET Web API 控制器创建过程(一) 前言 在前面对管道.路由有了基础的了解过后,本篇将带大家一起学习一下在ASP.NET Web API中控制器的创建过程,这过程分为几个部分下面的内 ...

  5. Spring MVC 学习 -- 创建过程

    Spring MVC 学习 -- 创建过程 Spring MVC我们使用的时候会在web.xml中配置 <servlet> <servlet-name>SpringMVC< ...

  6. Web APi之过滤器创建过程原理解析【一】(十)

    前言 Web API的简单流程就是从请求到执行到Action并最终作出响应,但是在这个过程有一把[筛子],那就是过滤器Filter,在从请求到Action这整个流程中使用Filter来进行相应的处理从 ...

  7. .NET/ASP.NET MVC Controller 控制器(IController控制器的创建过程)

    阅读目录: 1.开篇介绍 2.ASP.NETMVC IControllerFactory 控制器工厂接口 3.ASP.NETMVC DefaultControllerFactory 默认控制器工厂 4 ...

  8. 图解JAVA对象的创建过程

    前面几篇博文分别介绍了JAVA的Class文件格式.JVM的类加载机制和JVM的内存模型,这里就索性把java对象的创建过程一并说完,这样java对象的整个创建过程就基本上说明白了(当然你要有基础才能 ...

  9. JVM中对象的创建过程

    JVM中对象的创建过程如以下流程图中所示: 对其主要步骤进行详细阐述: 为新生对象分配内存: 内存的分配方式: 指针碰撞:假设Java堆中内存是绝对规整的,所有用过的内存放在一边,空闲的内存在另一边, ...

随机推荐

  1. 泛型约束where条件的使用(可以通过类型参数动态反射创建实例)

    定义抽象的人类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...

  2. /^\s+|\s+$/g 技术 内容

    alert(" aa dd ".replace(/^\s+|\s+$/g,'')+"方式的"); //正则表达式解释:分成两部分,^\s+ 以空格开头,\s+$ ...

  3. 外网不能访问阿里云服务器的apache服务

    今天弄了下Ubuntu的服务器,配置了一个LAMP环境的服务器,配置有时间我再来说 但是配置了很长的时间,差不都怕是好几个小时 在配置apache的时候,出现了问题,好不容易把apache服务配置好 ...

  4. 构造函数constructor 与析构函数destructor(四)

    拷贝构造函数:拷贝构造函数就是在用一个类对象来创建另外一个类对象时被调用的构造函数,如果我们没有显示的提供拷贝构造函数,编译器会隐式的提供一个默认拷贝构造函数. 拷贝构造函数的定义是X(const X ...

  5. 2018.09.20 atcoder Painting Graphs with AtCoDeer(tarjan+polya)

    传送门 一道思维题. 如果没有环那么对答案有k的贡献. 如果恰为一个环,可以用polya求贡献. 如果是一个有多个环重叠的双联通的话,直接转化为组合数问题(可以证明只要每种颜色被选取的次数相同一定可以 ...

  6. php一些方法说明

    var_dump():判断一个变量的类型与长度,并输出变量的数值,如果变量有值输的是变量的值并回返数据类型.此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值.数组将递归展开值,通过缩进显 ...

  7. 团队博客-第六周:Alpha阶段项目复审(科利尔拉弗队)

    团队的排名-点评:以下排名点评谨代表个人观点,如有冒犯,评论联系删除 小组名字和链接 优点 缺点,bug报告(至少140字) 最终名次(无并列) 中午吃啥队 微信小程序应用,新型app会是一个便利的使 ...

  8. [mobile]移动端页面没有重新请求时,刷新页面代码

    <input type="hidden" value="yes" id="id_if_reload" /> <script ...

  9. [label][politic-video]李锡锟的政治学视频下载链接

    李锡锟政治学 1.http://r15---sn-p5qlsn7y.googlevideo.com/videoplayback?initcwndbps=1471000&signature=09 ...

  10. EBS获取附件URL

    http://wenku.baidu.com/link?url=MnYX269RBqW9ZRh-4famwduhYq9As0-vsIyVPA7aqv64cdxxjZEOaEE1_KZ9SGjY9qCx ...