//定义Person类
class Person: NSObject { var name: String? //注意这里基本数据类型我定义的是必选属性
var age: Int = override init() { super.init() } // MARK: - 定义类方法 查看本类的属性列表
class func demo() -> () { var outCount: UInt32 = //调用runtime 方法 class_copyPropertyList 获取类的公有属性列表
let propertyList = class_copyPropertyList(self, &outCount) //遍历数组
for i in ..<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 = //调用runtime 方法 class_copyPropertyList 获取类的公有属性列表
let propertyList = class_copyPropertyList(self, &outCount) //遍历数组
for i in ..<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 = //调用runtime 方法 class_copyPropertyList 获取类的公有属性列表
let propertyList = class_copyPropertyList(self, &outCount) //遍历数组
for i in ..<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列表同理。。。