标签:from container body ons nta tin scl www 元素
对于C#、Java开发人员来说,肯定都对反射这个概念相当熟悉。所谓反射就是可以动态获取类型、成员信息,同时在运行时(而非编译时)可以动态调用任意方法、属性等行为的特性。
|
1
2
3
4
|
let children: Children //对象的子节点。displayStyle: Mirror.DisplayStyle? //对象的展示风格let subjectType: Any.Type //对象的类型func superclassMirror() -> Mirror? //对象父类的 mirror |
|
1
2
3
4
5
6
7
|
//用户类class User { var name:String = "" //姓名 var nickname:String? //昵称 var age:Int? //年龄 var emails:[String]? //邮件地址} |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
//创建一个User实例对象let user1 = User()user1.name = "hangge"user1.age = 100user1.emails = ["hangge@hangge.com","system@hangge.com"] //将user对象进行反射let hMirror = Mirror(reflecting: user1) print("对象类型:\(hMirror.subjectType)")print("对象子元素个数:\(hMirror.children.count)") print("--- 对象子元素的属性名和属性值分别如下 ---")for case let (label?, value) in hMirror.children { print("属性:\(label) 值:\(value)")} |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
//根据属性名字符串获取属性值func getValueByKey(obj:AnyObject, key: String) -> Any { let hMirror = Mirror(reflecting: obj) for case let (label?, value) in hMirror.children { if label == key { return unwrap(value) } } return NSNull()}//将可选类型(Optional)拆包func unwrap(any:Any) -> Any { let mi = Mirror(reflecting: any) if mi.displayStyle != .Optional { return any } if mi.children.count == 0 { return any } let (_, some) = mi.children.first! return some} |
|
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
|
//创建一个User实例对象let user1 = User()user1.name = "hangge"user1.age = 100user1.emails = ["hangge@hangge.com","system@hangge.com"]//通过属性名字符串获取对应的值let name = getValueByKey(user1, key: "name")let nickname = getValueByKey(user1, key: "nickname")let age = getValueByKey(user1, key: "age")let emails = getValueByKey(user1, key: "emails")let tel = getValueByKey(user1, key: "tel")print(name, nickname, age, emails, tel)//当然对于获取到的值也可以进行类型判断if name is NSNull { print("name这个属性不存在")}else if (name as? AnyObject) == nil { print("name这个属性是个可选类型,且为nil")}else if name is String { print("name这个属性String类型,其值为:\(name)")}if nickname is NSNull { print("nickname这个属性不存在")}else if (nickname as? AnyObject) == nil { print("nickname这个属性是个可选类型,且为nil")}else if nickname is String { print("nickname这个属性String类型,其值为:\(nickname)")}if tel is NSNull { print("tel这个属性不存在")}else if (tel as? AnyObject) == nil { print("tel这个属性是个可选类型,且为nil")}else if tel is String { print("tel这个属性String类型,其值为:\(tel)")} |
|
1
2
3
4
5
6
7
|
//用户类class User: NSObject{ var name:String = "" //姓名 var nickname:String? //昵称 var age:Int = 0 //年龄 var emails:[String]? //邮件地址} |
|
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
|
//创建一个User实例对象let user1 = User()user1.name = "hangge"user1.age = 100user1.emails = ["hangge@hangge.com","system@hangge.com"]//使用KVC取值let name = user1.valueForKey("name")let nickname = user1.valueForKey("nickname")let age = user1.valueForKey("age")let emails = user1.valueForKey("emails")//let tel = user1.valueForKey("tel")print(name, nickname, age, emails) //当然对于获取到的值也可以进行类型判断if name == nil { print("name这个属性是个可选类型,且为nil")}else if name is String { print("name这个属性String类型,其值为:\(name)")} if nickname == nil { print("nickname这个属性是个可选类型,且为nil")}else if nickname is String { print("nickname这个属性String类型,其值为:\(nickname)")} |
|
1
2
3
4
5
6
7
8
9
|
//创建一个User实例对象let user1 = User()//使用KVC赋值user1.setValue("hangge", forKey: "name")user1.setValue(100, forKey: "age")user1.setValue(["hangge@hangge.com","system@hangge.com"], forKey: "emails") print(user1.name, user1.nickname, user1.age, user1.emails) |
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_976.html
http://www.hangge.com/blog/cache/detail_976.html
Swift - 反射(Reflection)的介绍与使用样例(附KVC介绍)
标签:from container body ons nta tin scl www 元素
原文地址:https://www.cnblogs.com/feng9exe/p/9105757.html