iOS 之Mirror的使用
使用Mirror可以在不获取对象文件的情况下,知悉该对象所有的属性,不管是私有还是公开的。
class Animal: NSObject { private var food = "" override init() { super.init() self.food = "meat" } } class Human: Animal { private var height: Float = 0.0 private var weight: Float = 0.0 override init() { super.init() self.height = 170 self.weight = 120 } } class Person: Human { private var name: String = "" //String private var gender: String = "" //String private var family: [Person] = [] //Array<Person> private var pDic: [String: String] = [:] //Dictionary<String, String> override init() { super.init() self.name = "zhou" self.gender = "men" self.family = [] self.pDic = ["hair": "black", "eyes": "black"] } }
随便定义三个类,Person -> Human -> Animal 这是他们的继承关系。
let p = Person() var mir: Mirror = Mirror(reflecting: p) for item in mir.children { let value = item.value let valueType = "\(Mirror(reflecting: value).subjectType)" debugPrint(item.label!, item.value, valueType) // p.setValue(<#T##value: Any?##Any?#>, forKey: <#T##String#>) } =============debugPrint================= "name" "zhou" "String" "gender" "men" "String" "family" [] "Array<Person>" "pDic" ["hair": "black", "eyes": "black"] "Dictionary<String, String>"
以上初始化了一个Person类对象p,然后查看其所有的属性并打印字段名、值、值类型。拿到了这些信息,就可以做一些操作了比如setValue:forKey直接修改属性值。而且还可以获取对象所继承的相关信息,看以下例子:
let p = Person() var mir: Mirror = Mirror(reflecting: p) let baseType = Animal.self var selfMirrorType = mir.subjectType while true { for item in mir.children { let value = item.value let valueType = "\(Mirror(reflecting: value).subjectType)" debugPrint(item.label ?? "label", item.value, valueType) } debugPrint("===========================================") if let superclassMirror = mir.superclassMirror { mir = superclassMirror selfMirrorType = superclassMirror.subjectType } else { break } }
循环查找对象的superclassMirror直到为空,以下是打印信息:先打印Person类,再是继承的Human类信息,最后是基类Animal信息。
"name" "zhou" "String" "gender" "men" "String" "family" [] "Array<Person>" "pDic" ["hair": "black", "eyes": "black"] "Dictionary<String, String>" "===========================================" "height" 170.0 "Float" "weight" 120.0 "Float" "===========================================" "food" "meat" "String" "===========================================" "==========================================="
如果你不想Mirror打印一个类所有属性的话,可以给类添加一个扩展遵循协议CustomReflectable:当对Person类使用Mirror时,我们只让查看name和gender属性。
extension Person: CustomReflectable { var customMirror: Mirror { return Mirror(Person.self, children: ["name": self.name, "gender": self.gender], displayStyle: .class, ancestorRepresentation: .suppressed) } } let p = Person() var mir: Mirror = Mirror(reflecting: p) for item in mir.children { let value = item.value let valueType = "\(Mirror(reflecting: value).subjectType)" debugPrint(item.label!, item.value, valueType) } ==========================debugPrint===================================== "name" "zhou" "String" "gender" "men" "String"
ps;iOS开发交流技术群:欢迎你的加入 ,不管你是大牛还是小白都欢迎入驻 ,分享BAT,阿里面试题、面试经验,讨论技术, 大家一起交流学习成长!