今天继续来一篇水文,关于 Alamofire 和 RxSwift 两个组件中扩展后缀 .af 以及 .rx 是怎么实现的。相信用过的 ( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ 都看过了。我这里权当自己的记录流水账了。
先来看 Alamofire 中关于 af 扩展的实现:

使用 Alamofire 扩展的方式如下:
1
2
3
4
5
6
7
8
9
|
struct Demo {}
extension Demo: AlamofireExtended {}
extension AlamofireExtension where ExtendedType == Demo {
func printSomething() {
print("Something arrived.")
}
}
let d = Demo()
d.af.printSomething()
|
这里主要有两点:
1. 为将要使用的类 Demo 扩展 AlamofireExtended
协议,也就是增加 af 扩展属性,其返回的是一个封装对象 AlamofireExtension
;
2. 为 AlamofireExtension
对象(1 中返回的封装类型)扩展专属于 Demo 这个类型的方法;
说实话,这里用来封装元类型信息的结构体名称和扩展协议名称一样,我初次看的时候确实是蒙的。相对于 Alamofire 的命名来说,个人更喜欢 RxSwift 的命名。
接下来是 RxSwift 中 Rx 扩展的实现:

可以看到,整个使用方式上是完全相同的。仅仅是各项名字不同。
所以我们可以总结这种方式的使用路径,如何为我们自己开发的组件扩充命名空间,具体有三个地方:
声明扩展属性
为了能够支持实例变量和类型两者,需要分别增加两个计算属性:
- 一个是 static 的,提供给类型使用;
- 一个是实例变量,提供给单个实例来用;
封装元类型信息
为了能够使得 .af/.rx
这些扩展属性也能够获得当前实例或者类型的元信息,不约而同的使用了结构体封装的形式,通过泛型类型实现。我们知道这个封装对象内部就是记录的就是 self
我们可以通过编译器提示来看下扩展返回的类型是什么。

从 print 这个方法可以推断出,这个类型是个 AlamofireExtension
对象(因为我们是针对该类型增加的扩展方法),并且其内部有个变量 type 就是我们扩展的类型 Demo
。而我们为该对象扩展的方法 printSomething
也能够在实例是 Demo 类型的时候触发。
扩展目标类
我们已经知道扩展后缀拿到的是一个携带了关联类型的对象,因为有了关联类型,所以才能够通过 Where 子句写出针对不同类型存在的专属方法。
按照这个步骤,我们可以在自己的工程中写属于自己模块的扩展。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
import Foundation
// We implemented a module named Wonderful.
// Extension name will be named as wf
// Step 0.
// Encapsulate a type which is unknown until now.
struct Extensible<EncapsulatedType> {
let type: EncapsulatedType
init(_ type: EncapsulatedType) {
self.type = type
}
}
// Step 1.
// Extension a type to add two properties. a static var and a var
protocol WonderfulExtension {
associatedtype ExtendedType
// static entry point
static var wf: Extensible<ExtendedType>.Type { get set }
// instance entry point
var wf: Extensible<ExtendedType> { get set }
}
// Step 2.
extension WonderfulExtension {
static var wf: Extensible<Self>.Type {
set { }
get { return Extensible<Self>.self }
}
var wf: Extensible<Self> {
set { }
get { return Extensible(self) }
}
}
// Step3.
// Extend the type we want to, which the type will have wf var.
struct Ordinary {}
extension Ordinary: WonderfulExtension {}
// Step4.
// Restrict methods in the scope of type we want to extend
extension Extensible where EncapsulatedType == Ordinary {
func wow() {
print("Wow, Wonderful extension.")
}
}
// Use methods of wf extension
let obj = Ordinary()
obj.wf.wow()
|
总体上对于这种形式,带来两个显著的好处:
1. 明确作用域,告知调用者调用的专属方法属于该组件相关;
2. 提供该扩展的组件自身就更容易被扩展了(打上了烙印),也有了 RxSwift 所衍生的各种组件;
所以,这段代码中涉及的 Swift 类型系统中的几个关键支持:
1. 关联类型, Associated Type
2. 泛型系统, Generic
3. 扩展的默认实现, Extension Default Implementation
