Swift如何不创建实例获取符合Service协议类的属性类型
获取遵循Service协议类的属性类型字典(无需实例)
实现思路
由于你的Service协议继承自NSObject,所有实现类都能与Objective-C运行时交互,我们可以直接通过Objective-C运行时API提取类的属性类型信息,全程不需要创建类实例。
完整代码实现
import Foundation protocol Service: NSObject {} // 已有的全局类获取方法 private static func allClasses<R>() -> [R] { var count: UInt32 = 0 let classListPtr = objc_copyClassList(&count) defer { free(UnsafeMutableRawPointer(classListPtr)) } let classListBuffer = UnsafeBufferPointer(start: classListPtr, count: Int(count)) return classListBuffer.compactMap { $0 as? R } } // 解析属性的类型编码字符串 private static func parsePropertyType(from attributes: String) -> String? { // 属性编码格式示例:"T@\"NSString\",C,N,V_name",T字段后为类型信息 guard let typeMatch = attributes.range(of: #"T(.*?),"#, options: .regularExpression) else { return nil } let rawType = String(attributes[typeMatch].dropFirst().dropLast()) // 处理OC对象类型(如@"NSString") if rawType.hasPrefix("@\"") && rawType.hasSuffix("\"") { return String(rawType.dropFirst(2).dropLast()) } // 映射基本类型到Swift名称 switch rawType { case "i": return "Int" case "f": return "Float" case "d": return "Double" case "B": return "Bool" case "@": return "AnyObject" default: return rawType } } // 构建目标字典 static func buildServicePropertyMap() -> [String: [String]] { var propertyMap = [String: [String]]() // 筛选所有遵循Service协议的NSObject子类 let serviceClasses: [NSObject.Type] = allClasses().filter { class_conformsToProtocol($0, Service.self) } for serviceClass in serviceClasses { let className = NSStringFromClass(serviceClass) var propertyCount: UInt32 = 0 guard let properties = class_copyPropertyList(serviceClass, &propertyCount) else { propertyMap[className] = [] continue } defer { free(UnsafeMutableRawPointer(properties)) } var typeList = [String]() for index in 0..<Int(propertyCount) { let property = properties[index] let attrString = String(cString: property_getAttributes(property)) if let type = parsePropertyType(from: attrString) { typeList.append(type) } } propertyMap[className] = typeList } return propertyMap }
关键细节说明
- 类筛选:用
class_conformsToProtocol直接判断类是否遵循Service协议,不需要实例化。 - 类型解析:通过
property_getAttributes拿到属性的底层编码,解析后转换为Swift风格的类型名称,覆盖对象类型和基本数据类型。 - 无实例依赖:所有操作基于类的元数据,完全不需要创建类的实例对象,避免不必要的初始化开销。
内容的提问来源于stack exchange,提问作者Bohdan Savych
相关产品推荐
相关产品推荐

