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"
网友评论