Swift   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了Swift中的反射大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

概述

关键词 Swift 反射 Mirror Representation of the sub-structure and optional "display style" of any arbitrary subject instance. Describes the parts---such as stored properties, collection elements, tuple ele

关键词

Swift 反射 Mirror

Representation of the sub-structure and optional "display style" of any arbitrary subject instance.

Describes the parts---such as stored properties,collection elements,tuple elements,or the active enumeration case---that make up a particular instance. May also supply a "display style" property that suggests how this structure might be rendered.
/// A collection of `Child` elements describing the structure of the
/// reflected subject.
public let children: Children

/// Suggests a display style for the reflected subject.
public let displayStyle: Mirror.DisplayStyle?
@warn_unused_result
public func superclassMirror() -> Mirror?

children记录了该object下的变量(注:此处object为广义的定义)
displayStyle表示该object的类型(同上)
superclassMirror,顾名思义,表示其父类的Mirror

public enum DisplayStyle {
        case Struct
        case Class
        case Enum
        case Tuple
        case Optional
        case Collection
        case Dictionary
        case Set
    }

根据displayStyle的类型去判断类型再做分类讨论,其中Optional是Swift中独有比较特别的类型,需要特殊处理,当displayStyle为nil时,表示为基本数据类型

最后通过superclassMirror一层一层递归,去遍历所有变量

func getModel(Dic:Dictionary<String,Any>,objName:string) -> MYDataModel {
        let modelClass = NSClassFromString(objName) as! MYDataModel.Type
        model = modelClass.init()
        var mirror:Mirror? = Mirror(reflecTing: model)
        while (mirror != nil) {
            traverseProperty(Dic,mirror,model)
            mirror = mirror!.superclassMirror()
        }
        return model
    }

private func traverseProperty(Dic:Dictionary<String,_ mirror:Mirror?,_ model:MYDataModel) {
        if (mirror == nil) {
            return
        } else {
            for (_,value) in mirror!.children.enumerate() {
                let propertyName:string = value.label == nil ? "" : value.label!
                let properValue = value.value
                let DictionaryValue = Dic[propertyName]
                let tmp = Mirror(reflecTing: propervalue)
                if (DictionaryValue != nil) {
                    if (tmp.displayStyle != nil) {
                        switch tmp.displayStyle! {
                        case .Class:
                            if let DicValue = DictionaryValue as? [String: String] {
                                let anyClass = model.classForCoder as? NSObject.Type
                                let arrayTypename = anyClass!.performSELEctor(SELEctor("\(propertyName)Type")).takeRetainedValue() as? String
                                let anyArrayClass = NSClassFromString(arrayTypename!) as! MYDataModel.Type
                                let obj = anyArrayClass.init()
                                traverseProperty(DicValue,Mirror(reflecTing: obj),obj)
                                model.SETVALue(obj,forKey: propertyName)
                            }
                        case .Collection:
                            let anyClass = model.classForCoder as? NSObject.Type
                            let arrayTypename = anyClass!.performSELEctor(SELEctor("\(propertyName)Type")).takeRetainedValue() as? String
                            switch arrayTypename! {
                            case MYDataModelType.String.rawValue:
                                if let arrayValue =  DictionaryValue as? [String] {
                                    if (arrayValue.count > 0) {
                                        model.SETVALue(arrayValue,forKey: propertyName)
                                    }
                                }
                            default:
                                if let arrayValue =  DictionaryValue as? [[String: String]] {
                                    var resultArray = [(NSClassFromString(arrayTypename!) as! MYDataModel.TypE).init()]
                                    for item in arrayValue {
                                        let anyArrayClass = NSClassFromString(arrayTypename!) as! MYDataModel.Type
                                        let obj = anyArrayClass.init()
                                        traverseProperty(item,obj)
                                        resultArray.append(obj)
                                    }
                                    model.SETVALue(resultArray,forKey: propertyName)
                                }
                                break
                            }
                        case .Dictionary:
                            print("Dictionary")
                        case .optional:
                            if (tmp.children.count > 0) {
                                for (_,value2) in tmp.children.enumerate() {
                                    let properValue2 = value2.value
                                    switch properValue2 {
                                    case _ as Bool:
                                        if let boolValue =  DictionaryValue as? Bool {
                                            model.SETVALue(NSnumber(bool:boolvalue),forKey: propertyName)
                                        }
                                    case _ as Int:
                                        if let intValue =  DictionaryValue as? Int {
                                            model.SETVALue(NSnumber(Integer: intvalue),forKey: propertyName)
                                        }
                                    case _ as Float :
                                        if let floatValue =  DictionaryValue as? Float {
                                            model.SETVALue(NSnumber(float: floatvalue),forKey: propertyName)
                                        }
                                    case _ as Double :
                                        if let doubleValue =  DictionaryValue as? Double {
                                            model.SETVALue(NSnumber(double: doublevalue),forKey: propertyName)
                                        }
                                    case _ as String:
                                        if let stringvalue =  DictionaryValue as? String {
                                            model.SETVALue(stringvalue,forKey: propertyName)
                                        }
                                    default:
                                        print("\(propertyName) is an unkown optional value")
                                        break
                                    }
                                }
                            } else {
                                print("\(propertyName) is an unkown value")
                                if let objValue =  DictionaryValue as? AnyObject {
                                    model.SETVALue(objValue,forKey: propertyName)
                                }
                            }
                        default:
                            break
                        }
                    } else {
                        switch properValue {
                        case _ as Bool:
                            if let boolValue =  DictionaryValue as? Bool {
                                model.SETVALue(NSnumber(bool:boolvalue),forKey: propertyName)
                            }
                        case _ as Int:
                            if let intValue =  DictionaryValue as? Int {
                                model.SETVALue(NSnumber(Integer: intvalue),forKey: propertyName)
                            }
                        case _ as Float :
                            if let floatValue =  DictionaryValue as? Float {
                                model.SETVALue(NSnumber(float: floatvalue),forKey: propertyName)
                            }
                        case _ as Double :
                            if let doubleValue =  DictionaryValue as? Double {
                                model.SETVALue(NSnumber(double: doublevalue),forKey: propertyName)
                            }
                        case _ as String:
                            if let stringvalue =  DictionaryValue as? String {
                                model.SETVALue(stringvalue,forKey: propertyName)
                            }
                        default:
                            break
                        }
                    }
                }

            }
        }
    }

源码地址:https://github.com/VictorWuSH/SwiftExercise

大佬总结

以上是大佬教程为你收集整理的Swift中的反射全部内容,希望文章能够帮你解决Swift中的反射所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。