源链接:https://www.2cto.com/kf/201703/608892.html
ObjectMapper 学习笔记
那么多年过去了,从来没有认认真真的写过一回日是记,最近在看 ObjectMapper 的源代,写点日记记录点东西,帮助自己记忆。
要使用 ObjectMapper 必须实现Mappable接口中的以下两个方法:
|
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
|
/** 这个可用于mapping()方法前的一些验证* 返回nil就不会调用mapping()进行转换* 当然对像也就是nil了,可以对Map做一些条件判断*/init?(map: Map)/** 这个是对属性进行映射,如果这里没有对应的映射关系是不会映射的哦!!要记住了* 至于映射方法可以查看* Map.swift中下标(subscript)的方法* 和Operators.swift中自定义<-操作符的方法*/mutating func mapping(map: Map) |
具体的代码流程如下草图:
当我们使用自已的对像调用 public init?(JSONString: String)方法时,这时会去调Mappable协议顶层BaseMappable协议中public init?(JSONString: String, context: MapContext? = nil)方法的默认实现,代码如下:
|
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
|
public init?(JSONString: String, context: MapContext? = nil) {
if let obj: Self = Mapper(context: context).map(JSONString: JSONString) {
self = obj} else {
return nil
}}该方法中会去调用Mapper中的public func map(JSONString: String) -> N?方法,其代码如下:
/// Map a JSON string to an object that conforms to Mappablepublic func map(JSONString: String) -> N? {
if let JSON = Mapper.parseJSONStringIntoDictionary(JSONString: JSONString) {
return map(JSON: JSON)
}return nil
} |
这个方法中先做的第一件事是调用public static func parseJSONStringIntoDictionary(JSONString: String) -> [String: Any]?方法,将String类型的json串转成字典样式([String:Any])的对像,然后调用public func map(JSON: [String: Any]) -> N?方法进一步解析,这是调用最多也是最重要的一步,我们来看代码:
|
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
|
public func map(JSON: [String: Any]) -> N? {
let map = Map(mappingType: .fromJSON, JSON: JSON, context: context, shouldIncludeNilValues: shouldIncludeNilValues)if let klass = N.self as? StaticMappable.Type { // Check if object is StaticMappable
if var object = klass.objectForMapping(map: map) as? N {
object.mapping(map: map)return object
}} else if let klass = N.self as? Mappable.Type { // Check if object is Mappable
if var object = klass.init(map: map) as? N {
object.mapping(map: map)return object
}} else if N.self is ImmutableMappable.Type { // Check if object is ImmutableMappable
assert(false, "'ImmutableMappable' type requires throwing version of function \(#function) - use 'try' before \(#function)")
} else {
// Ensure BaseMappable is not implemented directlyassert(false, "BaseMappable should not be implemented directly. Please implement Mappable, StaticMappable or ImmutableMappable")
}return nil
} |
这里做的事情如下:
初始化一个map,做一些属性赋值,保存变量 调用自定义类的public init?(map: Map)方法,生成对象,如果返回nil就退出 调用自定义类的mutating mapping(map: Map)方法,开始映射。
1.首先会调用Map类中的各中下标方法(subscript方法),判断[String:Any]中是否存在与下标对应的字段,如果存在就将其值取出来,如果不存在跳过 2.再通过Operators类中的<-自定义操作符中取出来的值赋值给生成对象中的属性。
经过这样的转换之后就完成了从String到对象初始化赋值的操作。