import Foundation
/// 如果需要用对应的类型,字典定义Dictionary<String, Any>,对应value为Int8.self、Int16.self,下面用到的方法都需要更改为Dictionary<String, Any>
let valueTypesMap: Dictionary<String, String> = [
"c" : "Int8",
"s" : "Int16",
"i" : "Int32",
"q" : "Int", //also: Int64, NSInteger, only true on 64 bit platforms
"S" : "UInt16",
"I" : "UInt32",
"Q" : "UInt", //also UInt64, only true on 64 bit platforms
"B" : "Bool",
"d" : "Double",
"f" : "Float",
"{" : "Decimal"
]
extension NSObject {
/// 获取继承自该类的所有子类
///
/// - Returns: 子类名称数组
class func subclasses() -> [NSString] {
var count: UInt32 = 0, result: [NSString] = []
let allClasses = objc_copyClassList(&count)!
for n in 0 ..< count {
let someClass: AnyClass = allClasses[Int(n)]
guard let someSuperClass = class_getSuperclass(someClass), String(describing: someSuperClass) == String(describing: self) else { continue }
//返回的类会带module名,如果把module名截取了,就无法转换成对应的类了
let className: NSString = NSStringFromClass(someClass) as NSString
result.append(className)
}
return result
}
/// 获取属性名和类型列表
///
/// - Returns: 属性名和类型的字典
class func getProperties() -> Dictionary<String, String>? {
var count = UInt32()
guard let properties = class_copyPropertyList(self, &count) else { return nil }
var types: Dictionary<String, String> = [:]
for i in 0..<Int(count) {
let property: objc_property_t = properties[i]
/// 获取属性名
guard let name = getNameOf(property: property)
else { continue }
/// 获取属性类型
let type = getTypeOf(property: property)
types[name] = type
}
free(properties)
return types
}
/// 获取属性名
///
/// - Parameter property: 属性对象
/// - Returns: 属性名
private class func getNameOf(property: objc_property_t) -> String? {
guard
let name: NSString = NSString(utf8String: property_getName(property))
else { return nil }
return name as String
}
/// attributes对应的类型
///
/// - Parameter attributes: attributes
/// - Returns: 类型名
private class func valueType(withAttributes attributes: String) -> String? {
let tmp = attributes as NSString
let letter = tmp.substring(with: NSMakeRange(1, 1))
guard let type = valueTypesMap[letter] else { return nil }
return type
}
/// 获取属性类型
///
/// - Parameter property: 属性对象
/// - Returns: 属性类型
private class func getTypeOf(property: objc_property_t) -> String? {
guard let attributesAsNSString: NSString = NSString(utf8String: property_getAttributes(property)!) else { return nil }
let attributes = attributesAsNSString as String
let slices = attributes.components(separatedBy: "\"")
guard slices.count > 1 else { return valueType(withAttributes: attributes) }
let objectClassName = slices[1]
return objectClassName
}
}
@objcMembers//必须有这一句,否则无法获取该类的所有属性列表
class Person: NSObject {
var id : Int = 0
var name: String = ""
var female: Bool = false
}
P.S:只能获取公有属性