Swift中的反射
来源:互联网 发布:华为mate7root软件 编辑:程序博客网 时间:2024/05/17 08:11
关键词
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_resultpublic 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, Any>, _ 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, Mirror(reflecting: obj), 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
0 0
- Swift中的反射
- Swift中的反射
- 015--Swift反射机制
- [Swift]Swift中的!和?
- Swift反射API及其用法
- Swift 反射Mirror的使用
- [Swift]Swift 中的指针使用
- .Net 中的反射(反射特性)
- .Net 中的反射(反射特性)
- swift反射──Mirror(swift 2.0)
- Swift 基本知识之十八 swift格式化输出和反射机制
- 由swift想到的-python反射机制
- iOS学习笔记48-Swift(八)反射
- iOS开发技巧系列 使用Swift反射
- 【Swift】反射(Reflection)的介绍
- swift通过类名反射创建类
- [iOS]Swift-反射机制及KVC
- 【Swift】中的一些关键字
- 你不知道的那些“XX即服务”
- HEVC算法和体系结构:预测编码之帧内预测
- mybatis foreach @Param("*")
- java.sql.SQLException: Value '0000-00-00 00:00:00' can not be represented as java.sql.Timestamp
- 函数指针的使用
- Swift中的反射
- 最小生成树
- 防采集方法
- 从Hadoop到Spark
- 数组的基本操作(二)
- Nginx绑定域名 nginx绑定多个域名
- Floyd判圈算法理解
- OVER(PARTITION BY)函数用法
- C语言实现链表之双向链表(三)创建链表