swift3.0 运行时获取类的属性
//定义Person类 class Person: NSObject { var name: String? //注意这里基本数据类型我定义的是必选属性 var age: Int = 10 override init() { super.init() } // MARK: - 定义类方法 查看本类的属性列表 class func demo() -> () { var outCount: UInt32 = 0 //调用runtime 方法 class_copyPropertyList 获取类的公有属性列表 let propertyList = class_copyPropertyList(self, &outCount) //遍历数组 for i in 0..<Int(outCount) { // 取出数组中的元素 objc_property_t? let pty = propertyList?[i] // 获取属性名称 是C字符串 UnsafePointer<Int8>? let cName = property_getName(pty!) //转换成OC String? let oName = String(utf8String: cName!) print(oName ?? "") } //因为propertyList数组是copy出来的,所以要释放数组 free(propertyList) } }
此时会输出name age ; 如果是基本数据类型的属性:int float .... 必须给属性赋初值 ,不然运行时获取不到该属性:
//定义Person类 class Person: NSObject { var name: String? //注意这里基本数据类型我定义的是可选属性 var age: Int? override init() { super.init() } // MARK: - 定义类方法 查看本类的属性列表 class func demo() -> () { var outCount: UInt32 = 0 //调用runtime 方法 class_copyPropertyList 获取类的公有属性列表 let propertyList = class_copyPropertyList(self, &outCount) //遍历数组 for i in 0..<Int(outCount) { // 取出数组中的元素 objc_property_t? let pty = propertyList?[i] // 获取属性名称 是C字符串 UnsafePointer<Int8>? let cName = property_getName(pty!) //转换成OC String? let oName = String(utf8String: cName!) print(oName ?? "") } //因为propertyList数组是copy出来的,所以要释放数组 free(propertyList) } }
此时会输出name , 也就是基本数据类型的属性, 如果是可选的, 那么运行时获取不到该属性。所以大家在定义属性的时候要谨慎, 尤其是字典转模型的时候要注意。
swift增加的guard守护,可以帮助我们解决可选值的烦恼,那么 我们优化一下代码
class Person: NSObject { var name: String? //注意这里基本数据类型我定义的是可选属性 var age: Int? override init() { super.init() } // MARK: - 定义类方法 查看本类的属性列表 class func demo() -> () { var outCount: UInt32 = 0 //调用runtime 方法 class_copyPropertyList 获取类的公有属性列表 let propertyList = class_copyPropertyList(self, &outCount) //遍历数组 for i in 0..<Int(outCount) { guard let pty = propertyList?[i], let cName = property_getName(pty), let oName = String(utf8String: cName) else{ //如果 pty cName oName 不存在的话 继续遍历下一个 continue } print(oName) } //因为propertyList数组是copy出来的,所以要释放数组 free(propertyList) } }
获取ivar列表同理。。。