[iOS]Swift-反射机制及KVC
2017-02-14 10:25
531 查看
Swift中的反射
在Swift中并不提倡使用Runtime,而是像其他语言一样使用反射(Reflect)。当然,目前Swift中的反射还没有其他语言中的反射功能强大,不仅远不及OC的Runtime,离Java的反射也有一定的距离。Swift的反射机制是基于一个叫 Mirror 的 struct 来实现的,其内部有如下属性和方法:
let children: Children //对象的子节点。
displayStyle: Mirror.DisplayStyle? //对象的展示风格
let subjectType: Any.Type //对象的类型
func superclassMirror() -> Mirror? //对象父类的 mirror
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_976.html*/
在Swift中并不提倡使用Runtime,而是像其他语言一样使用反射(Reflect)。当然,目前Swift中的反射还没有其他语言中的反射功能强大,不仅远不及OC的Runtime,离Java的反射也有一定的距离。Swift的反射机制是基于一个叫 Mirror 的 struct 来实现的,其内部有如下属性和方法:
let children: Children //对象的子节点。
displayStyle: Mirror.DisplayStyle? //对象的展示风格
let subjectType: Any.Type //对象的类型
func superclassMirror() -> Mirror? //对象父类的 mirror
原文出自:www.hangge.com 转载请保留原文链接:http://www.hangge.com/blog/cache/detail_976.html*/
import UIKit class User { var name:String = "" var nickName:String? var age:Int? var emails:[String]? } let user = User() user.name = "lixiayi" user.age = 100 user.emails = ["hangge@hangge.com","system@hangge.com"] // 将User对象进行反射 let mirror = Mirror(reflecting: user) print("对象类型:\(mirror.subjectType)") print("对象子元素的个数:\(mirror.children.count)") print("--- 对象子元素的属性名和属性值分别如下 ---") for case let (label?, value) in mirror.children { print("属性:\(label) 值:\(value)") } // 根据属性名字符串获取属性值 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(any: value) } } return NSNull() } func unwrap(any:Any) -> Any { let mi = Mirror(reflecting: any) if mi.displayStyle != Mirror.DisplayStyle.optional { return any } if mi.children.count == 0 { return any } let (_, some) = mi.children.first! return some } // 创建一个User实例对象 let user1 = User() user1.name = "hangge" user1.age = 100 user1.emails = ["hangge@hangge.com","system@hangge.com"] // 通过属性名字符串获取对应的值 let name = getValueByKey(obj: user1, key: "name") let nickname = getValueByKey(obj: user1, key: "nickname") let age = getValueByKey(obj: user1, key: "age") let emails = getValueByKey(obj: user1, key: "emails") let tel = getValueByKey(obj: 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)") } /*KVC是key-value coding的缩写。它是一种间接访问对象的机制。其本质是依据OC中Runtime的强大动态能力来实现的。在Swift中,只要类继承NSObject即可使用KVC。(有一个叫KVO的,它又是基于KVC,大家有兴趣的可以自行研究下。) KVC中:key的值就是属性名称的字符串,返回的value是任意类型,需要自己转化为需要的类型。*/ class Teacher:NSObject { var name:String = "" //姓名 var nickname:String? //昵称 var age:Int = 0 //年龄 var emails:[String]? //邮件地址 } //创建一个User实例对象 let t1 = Teacher() t1.name = "hangge" t1.age = 100 t1.emails = ["hangge@hangge.com","system@hangge.com"] //使用KVC取值 let t_name = t1.value(forKey: "name") let t_nickname = t1.value(forKey: "nickname") let t_age = t1.value(forKey: "age") let t_emails = t1.value(forKey: "emails") //let tel = user1.valueForKey("tel") print(name, nickname, age, emails) //当然对于获取到的值也可以进行类型判断 if t_name == nil { print("t_name这个属性是个可选类型,且为nil") }else if t_name is String { print("t_name这个属性String类型,其值为:\(t_name)") } if t_nickname == nil { print("t_nickname这个属性是个可选类型,且为nil") }else if t_nickname is String { print("t_nickname这个属性String类型,其值为:\(t_nickname)") } //创建一个Teacher实例对象 let t2 = Teacher() //使用KVC赋值 t2.setValue("newTeacher", forKey: "name") t2.setValue(100, forKey: "age") t2.setValue(["hangge@hangge.com","system@hangge.com"], forKey: "emails") print(t2.name, t2.nickname, t2.age, t2.emails)
相关文章推荐
- Java反射随记
- AS3中的反射(速记) 分析
- Java Runtime Environment 5.0 Update 12 下载
- C# 反射(Reflection)的用处分析
- C#通过反射创建自定义泛型
- 通俗易懂的C#之反射教程
- C#根据反射和特性实现ORM映射实例分析
- C# 使用反射来实现对象的深度复制方法
- 在C++中反射调用.NET的方法(二)
- 深入反射生成数组的详解
- C#利用反射来判断对象是否包含某个属性的实现方法
- C#利用反射技术实现去掉按钮选中时的边框效果
- C#泛型和反射实例解析
- C# Dynamic关键字之:dynamic为什么比反射快的详解
- C# 程序集和反射详解
- 传智播客学习之java 反射
- java中利用反射调用另一类的private方法的简单实例
- Java 反射之私有字段和方法详细介绍
- Java 反射机制详解及实例代码
- php set_magic_quotes_runtime() 函数过时解决方法