创建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. Confluence无法打开编辑器,一直在转圈

    在管理员界面中,将Collaborative editing 设置为Off 或者 Limited . 快速找到该界面的方式是,在搜索框里搜索 “Collaborative editing”. 折腾了几 ...

  2. Jfinal框架是什么框架?适用于什么项目呢?

    Jfinal框架是什么框架?适用于什么项目呢? jfinal 基于spring MVC研发的框架,操作简单.节省代码,适用于所有web项目.适合中小型项目开发.10分钟写出一个页面的增删改查.目前所在 ...

  3. 2018.09.24 bzoj1816: [Cqoi2010]扑克牌(二分答案)

    传送门 简单二分答案. 我们二分最终有k个牌堆. 这样joker被选择的张数≤min(k,m)\le min(k,m)≤min(k,m) 并且joker需要被选择的张数应该是∑i−1nmax(0,k− ...

  4. c语言学生信息管理系统-学习结构体

    #include<stdio.h> #include<stdlib.h> //结构体可以存放的学生信息最大个数,不可变变量 ; //学生信息结构体数组,最多可以存放100个学生 ...

  5. 编写属于自己的linux命令

    开篇: 问题和解决思路 在使用一些基础IDE时,工具经常会在我们建立特定文件时给我们一个已经有了一些特定代码的模板文件,但是在linux开发时,没有这样的IDE,怎么办?虽然代码量不是很多,但是能一次 ...

  6. Yarn application has already exited with state FINISHED

    如果在运行spark-sql时遇到如下这样的错误,可能是因为yarn-site.xml中的配置项yarn.nodemanager.vmem-pmem-ratio值偏小,它的默认值为2.1,可以尝试改大 ...

  7. C#-VS字符串、日期、时间和时间段

    小知识 哈希表,内存中的对象,用速度很快的哈希表当字典表,记录主键和内容. @,遇到转义字符,不转义,直接输出,即就是.转义字符是反斜杠/ 全部的内置类型都用类和结构描述.值类型用结构,引用类型用类. ...

  8. Difference between the Bill of distribution and sourcing rule.

        https://forums.oracle.com/thread/936768 This is from a users guide  Oracle Supply Chain Planning ...

  9. codis服务部署前的操作及初始化

    1.检查服务器ipv6模块是否打开,如果打开需要禁用ipv6,防止codis-dashbord连接zookeeper失败. 因为不确定codis-dashbord服务连接zookeeper使用ipv4 ...

  10. NetMQ 消息队列

    忘记是看到哪个博客写的了,如有侵权,请见谅!! 1.辅助Helper类 (添加System.Messaging引用) using System; using System.Collections.Ge ...