源链接: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)
|
具体的代码流程如下草图:
![这里写图片描述](https://www.2cto.com/uploadfile/Collfiles/20170308/20170308091258273.png)
当我们使用自已的对像调用 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 Mappable
public
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 directly
assert
(
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到对象初始化赋值的操作。