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

网络请求封装选Struct/Enum/Class?选型及包体积影响问题咨询

网络层类型选型问题解答

1. 此类场景优先使用Struct,Class可按需选择,Enum不适用

原因如下:

  • 你的网络层实现属于无状态服务,当前ModuleNetwork没有任何可变存储属性,所有逻辑都封装在方法内部,值类型的Struct完全能满足需求,不需要引用类型Class的引用计数额外开销
  • Struct天然线程安全:值类型在传递时是独立拷贝,多线程请求场景下不会出现多端同时修改同一个实例的问题,不需要额外加锁保证线程安全,适配网络请求的高并发特性
  • 你已经通过ModuleNetworkProvider协议完成了能力抽象,不需要用到Class的继承特性来做代码复用,协议+扩展的组合反而能更灵活地抽离通用逻辑(比如统一解码、统一错误处理)
  • 仅当你需要给网络层增加可变全局状态时(比如全局请求重试计数、自定义请求队列存储),再切换为Class即可,因为有协议做抽象,类型切换对上层调用方完全无感知
  • Enum完全不适用于该场景:Enum的设计目的是表达有限的同类型枚举值,哪怕用无case的Enum做命名空间,后续也无法扩展存储属性,灵活性远低于Struct

2. 使用Struct实现不会增大应用包体积

  • 无存储属性的Struct初始化不需要分配额外内存,运行时开销和全局函数几乎一致
  • Swift编译器对值类型有大量优化,这种无状态Struct的方法调用会在编译期做静态派发,比Class的动态派发性能更高,不会产生额外的运行时代码
  • 即便你有数十上百个类似的功能模块Struct实现,只要通过统一协议做抽象,编译后不会产生冗余代码,反而比零散的全局函数实现包体积更小

可选优化建议

你可以把通用解码逻辑抽成协议扩展,减少每个Struct实现的重复代码:

extension ModuleNetworkProvider {
    func decode<T: Decodable>(from data: Data, as type: T.Type) throws -> T {
        return try JSONDecoder().decode(T.self, from: data)
    }
}

调整后每个网络请求实现里的解码逻辑只需要调用该扩展方法即可,不需要重复写do-catch的解码模板代码。


内容的提问来源于stack exchange,提问作者Johhny Ios

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 18:03:01