创建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. 8.14 右键自定义菜单 更加iframe 内容高度调整 iframe高度 js定时

    <div class="main_contain" id="z_div" style="position: relative;"> ...

  2. cocos2d-js 安卓自定义本地通知功能

    安卓新手,笔记有理解不当的地方望指出,经过几天折腾终于可以实现类似ios的本地通知功能(ios就几行代码),可能有第三方sdk可以方便实现,暂时没去找 思路: 1. startService 和bin ...

  3. 关于adbd进程的ROOT权限问题

    http://blog.csdn.net/a345017062/article/details/6254402 adbd源码位于system/core/adb/目录下,可执行文件位于/sbin/adb ...

  4. 2018.08.06 bzoj1500: [NOI2005]维修数列(非旋treap)

    传送门 平衡树好题. 我仍然是用的fhqtreap,感觉速度还行. 维护也比线段树splay什么的写起来简单. %%%非旋treap大法好. 代码: #include<bits/stdc++.h ...

  5. Error setting expression 'XXX‘'[Ljava.lang.with value '[Ljava.lang.String;@10101fb'

    ognl报的警告,说明你的格式错误,一般是日期格式错误,格式转换器的应用,id设置的类型不对String 类型,输入了Int类型所以方法一是改变这个类中的id的属性 然后get和set也跟着改变 另一 ...

  6. tred_extract_EDED_new

    # -*- coding:utf-8 -*- import re ''' 适应新版本 ''' year='17a'#用户自定义 ss='./data/'#根目录 filename = ss+'EDED ...

  7. 14)settings.xml

    1. User Level. ${user.home}/.m2/settings.xml 2. Global Level. ${maven.home}/conf/settings.xml <se ...

  8. MySQL性能调优与架构设计——第 18 章 高可用设计之 MySQL 监控

    第 18 章 高可用设计之 MySQL 监控 前言: 一个经过高可用可扩展设计的 MySQL 数据库集群,如果没有一个足够精细足够强大的监控系统,同样可能会让之前在高可用设计方面所做的努力功亏一篑.一 ...

  9. android注解处理技术APT

    APT(Annotation Processing Tool)是java的注解处理技术,它对源代码文件进行检测找出其中的Annotation,根据注解和注解处理器和相应的apt自动生成代码. Anno ...

  10. spark ml 的例子

    一.关于spark ml pipeline与机器学习 一个典型的机器学习构建包含若干个过程 1.源数据ETL 2.数据预处理 3.特征选取 4.模型训练与验证 以上四个步骤可以抽象为一个包括多个步骤的 ...