You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 09:38:10