美文网首页iOS开发
iOS Mirror的使用

iOS Mirror的使用

作者: joeal | 来源:发表于2019-04-01 11:29 被阅读0次

    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"
    
    

    相关文章

      网友评论

        本文标题:iOS Mirror的使用

        本文链接:https://www.haomeiwen.com/subject/ybgmbqtx.html