iOS SnapKit架构之道(二)进入闭包

status
category
date
summary
slug
icon
tags
password
在上一篇中,简单介绍了snp.makeConstraints的调用栈,没有描述闭包之内代码的运行过程,这篇文章就探究一下闭包之内发生了什么。

简单用法

可以看到,make是闭包的关键所在,接下来继续研究上一篇探索过的ConstraintMaker

操作类ConstraintMaker

这是整个SnapKit中最关键的类,它将ConstraintViewConstraint联系到了一起,是将约束附加到控件上的工具。上篇文章中说道ConstraintMakerprepareConstraints方法中闭包的执行就避开不谈了,本文将从这里入手:
closure(maker)执行了闭包中的代码,例如:
这里的make.size到底是怎么实现的呢?makeConstraintMaker)有很多成员变量,包括一般使用的例如leftsize等等:
可以看到这些ConstraintMakerExtendable变量都是甩锅侠,都交给了self(ConstraintMaker)makeExtendableWithAttributes方法处理:
这个方法接受ConstraintAttributes作为参数,通过它和self.item,创建了一个ConstraintDescription,这里的self.item是一个LayoutConstraintItem,这是由上一篇提到的prepareConstraints静态方法,创建ConstraintMaker时将传入的ConstraintView转换而来的,实际上就是view.snp中的view;将这个description添加到self.descriptions数组后,将其作为参数,创建ConstraintMakerExtendable返回。

约束属性ConstraintAttributes

ConstraintAttributes是一个结构体,是makeExtendableWithAttributes的入参,也可以理解为make.size.equalToSuperview()中的size部分。同时,ConstraintAttributes遵循OptionSet协议和ExpressibleByIntegerLiteral协议,前者可以提供类似枚举但更加灵活的选项集合,后者可以通过整数字面量来初始化,看看它具体是怎么定义的:
可以看到size就是通过widthheight组合起来的,另外,在这个文件中,还重载了操作符:

链式多属性ConstraintMakerExtendable

ConstraintMakerExtendable继承自ConstraintMakerRelatable,通过父类的description变量的attributes数组实现链式的多属性,链式的实现也运用到了上面的重载过的操作符。

约束关系ConstraintMakerRelatable

这个类用于指定约束关系,例如equalTolessThanOrEqualTo等关系,最终都会调用relatedTo,然后返回ConstraintMakerEditable实例。
不同的约束关系通过枚举来实现:
不管是equalTo,还是lessThanOrEqualTo或者greaterThanOrEqual,最终都是调用relatedTo,只不过传入的枚举类ConstraintRelation不同而已。
而像equalToSuperview这种涉及到Superview的关系,都是在方法内部先获取到Superview,然后将其作为约束的目标对象,再通过对应的equalTo返回结果。
relatedTo主要是对传入的other: ConstraintRelatableTarget进行转型判断,根据不同结果对related: ConstraintItemconstant: ConstraintConstantTarget进行赋值,最终构造并返回一个ConstraintMakerEditable对象。

进阶约束ConstraintMakerEditable

ConstraintMakerEditable继承自ConstraintMakerPriortizable,主要用于设置约束的inset、offset等属性。
在这里又见到了@discardableResult,如果按照最初的例子make.size.equalTo(),到这里已经执行完毕了。这些方法只不过是更深入的操作,例如offset设置偏移量等等。

约束优先级ConstraintMakerPriortizable

ConstraintMakerPriortizable继承自ConstraintMakerFinalizable,主要用于设置优先级,然后返回ConstraintMakerPriortizable实例:

约束结果ConstraintMakerFinalizable

这是约束的最终结果,里面持有了ConstraintDescription实例,它可以完整地描述一条约束所需要的全部信息:
ConstraintDescription中,之前设置的属性,关系,乘除系数,优先级等因有尽有,定义如下:
获取了一个闭包中全部约束的全部信息之后,即执行闭包之后,下一步就是将这些描述信息全部添加到需要操作的view 上,这就是prepareConstraints所做的准备工作。接下来就是逐一激活这些约束。

总结

本文主要围绕SnapKit闭包中的内容,也就是make.size.equalTo()这行代码,了解了基本用到了哪些类,探究了约束创建的具体过程,学习了很多设计方案的具体实现,例如多属性的链式调用,可以通过子类返回父类的形式一级一级地返回。
Loading...

© 刘口子 2018-2025