这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战
昨天写了 一个小而美的 Swift 框架:Then 之后,有朋友说,居然没有源码解析。
Then 框架的核心代码不到 80 行,但是目前已经获得了 3.5k 的 star,着实让人佩服。
所以我感觉一个优秀的框架不在于多么庞大,而在是不是切实解决了开发者的某个痛点,提供了确切的帮助。
接下来,我们就来剖析一下这个短小精悍的框架。
then()
方法的定义:
public protocol Then {}
extension Then where Self: AnyObject {
/// Makes it available to set properties with closures just after initializing.
///
/// let label = UILabel().then {
/// $0.textAlignment = .center
/// $0.textColor = UIColor.black
/// $0.text = "Hello, World!"
/// }
@inlinable
public func then(_ block: (Self) throws -> Void) rethrows -> Self {
try block(self)
return self
}
}
复制代码
把上面的定义分成一个个的单词来看:
AnyObject
是一个空的协议,所有的类都实现了该协议。
可以放在 where
语句中,用于限定为类
类型。具体怎么限定,下面会提到。
self (小写的 s)
self
分成 3 种情况:
- 在方法内的
self
,比如常见的self.属性
,此处的self
表示具体的实例(类实例,结构体实例,枚举实例,等等); - 在某个 类型 后面的
.self
,比如UILabel.self
,表示类型本身; - 在某个 实例 后面也可以加
.self
,比如label.self
,还是表示这个实例本身(感觉没什么用)。
Self(大写的 S)
Self
经常用在和协议相关的地方,指代的是实现该协议的类型本身,也包括了这个类型的子类类型。
上面代码中,先看协议扩展(extension
)中出现的 Self
:
extension Then where Self: AnyObject {
}
复制代码
其中:
where
用来指定限制条件。Self: AnyObject
,此处的Self
就表示实现Then
协议的类型本身,或者这个类型的子类的类型。Self: AnyObject
就表示当前类型需要符合(实现了)AnyObject
协议。
连在一起就是,对实现了 Then
协议,并且符合 AnyObject
协议的类型进行扩展。
再看 then
方法定义上出现的 Self
:
// 为了方便理解,我把 throws,rethrows 移除了
func then(_ block: (Self) -> Void) -> Self {
}
复制代码
其中:
- 方法名为
then
; - 接收一个名为
block
的参数,参数类型为:(Self) -> Void
的闭包,这个闭包为:接收一个类型为Self
的参数,返回值类型为Void
; - 返回值的类型为
Self
;
这里的 Self
同样表示实现 Then
协议的类型本身,或者这个类型的子类的类型。
通过上面的解释后,我们再来完整的看一下代码:
extension Then where Self: AnyObject {
@inlinable
public func then(_ block: (Self) throws -> Void) rethrows -> Self {
try block(self)
return self
}
}
复制代码
即:对实现了 Then
协议,并且符合 AnyObject
协议的类型进行扩展;在扩展中添加了一个 then
方法,该方法接受一个类型为 (Self) -> Void
的闭包,返回值类型为该类型本身(即:Self
)。在 then
方法内执行了外界传入的 block
,并返回了当前实例(即:self
)。
Real World Example
拿一个真实的例子来举例:
let label = UILabel().then({ label in
label.textAlignment = .center
label.textColor = UIColor.black
label.text = "Hello, World!"
})
复制代码
等价于
let label = UILabel().then { label in
label.textAlignment = .center
label.textColor = UIColor.black
label.text = "Hello, World!"
}
复制代码
也等价于
let label = UILabel().then {
$0.textAlignment = .center
$0.textColor = UIColor.black
$0.text = "Hello, World!"
}
复制代码
首先,上面三段代码是等价的,但是代码逐渐简化了。
用图来表示执行结构就为:
参考
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END