1,反射(Reflection)
对于C#、Java开发人员来说,肯定都对反射这个概念相当熟悉。所谓反射就是可以动态获取类型、成员信息,同时在运行时(而非编译时)可以动态调用任意方法、属性等行为的特性。
以Java上的两个知名框架(hibernate和spring)为例。hibernate的属性映射就是通过反射来赋值的,spring的bean的创建就是根据配置的class来反射构建的。
2,Objective-C 的 Runtime
在使用ObjC开发时很少强调其反射概念,因为ObjC的Runtime要比其他语言中的反射强大的多。在ObjC中可以很简单的实现字符串和类型的转换(NSClassFromString()),实现动态方法调用(performSelector: withObject:),动态赋值(KVC)等等。
在使用ObjC开发时很少强调其反射概念,因为ObjC的Runtime要比其他语言中的反射强大的多。在ObjC中可以很简单的实现字符串和类型的转换(NSClassFromString()),实现动态方法调用(performSelector: withObject:),动态赋值(KVC)等等。
3,Swift中的反射
在Swift中并不提倡使用Runtime,而是像其他语言一样使用反射(Reflect)。当然,目前Swift中的反射还没有其他语言中的反射功能强大,不仅远不及OC的Runtime,离Java的反射也有一定的距离。
Swift的反射机制是基于一个叫 Mirror 的 struct 来实现的,其内部有如下属性和方法:
4,Swift反射的使用样例
在Swift中并不提倡使用Runtime,而是像其他语言一样使用反射(Reflect)。当然,目前Swift中的反射还没有其他语言中的反射功能强大,不仅远不及OC的Runtime,离Java的反射也有一定的距离。
Swift的反射机制是基于一个叫 Mirror 的 struct 来实现的,其内部有如下属性和方法:
4,Swift反射的使用样例
首先定义一个用户类:
接着创建一个用户对象,并通过反射获取这个对象的信息:
控制台输出信息如下:
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 = 100
//将user对象进行反射
let
hMirror =
Mirror
(reflecting: user1)
print
(
"对象类型:\(hMirror.subjectType)"
)
print
(
"对象子元素个数:\(hMirror.children.count)"
)
for
case
let
(label?,value)
in
hMirror.children {
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@H_502_435@
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)
return
any
}
if
mi.children.count == 0 {
return
any }
return
some
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@H_502_435@
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 = 100
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
{
}
else
if
(name
as
?
AnyObject
) ==
nil
{
}
else
if
name
is
String
{
}
if
nickname
is
NSNull
{
}
else
if
(nickname
as
?
AnyObject
) ==
nil
{
}
else
if
nickname
is
String
{
}
if
tel
is
NSNull
{
}
else
if
(tel
as
?
AnyObject
) ==
nil
{
}
else
if
tel
is
String
{
}
|
附:通过KVC访问属性值
因此用户类做如下改造:)
KVC是key-value coding的缩写。它是一种间接访问对象的机制。其本质是依据OC中Runtime的强大动态能力来实现的。在Swift中,只要类继承NSObject即可使用KVC。(有一个叫KVO的,它又是基于KVC,大家有兴趣的可以自行研究下。)
(注意:正由于KVC是基于Objective-C的,所以其不支持可选类型(optional)的属性,比如上例的 var age:Int?
因此用户类做如下改造:)
KVC主要就是两个方法:
(1)通过key获得对应的属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@H_502_435@
22
23
24
25
26
27
|
//创建一个User实例对象
let
user1 =
User
()
user1.name =
"hangge"
user1.age = 100
//使用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,emails)
//当然对于获取到的值也可以进行类型判断
if
name ==
nil
{
}
else
if
name
is
String
{
}
if
nickname ==
nil
{
}
else
if
nickname
is
String
{
}
|
(2)通过key设置对应的属性值
1
2
3
4
5
6
7
8
9
|
//创建一个User实例对象
let
user1 =
User
()
//使用KVC赋值
user1.setValue(
"hangge"
,forKey:
"name"
)
user1.setValue(100,forKey:
"age"
)
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
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。