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

如何声明可桥接为Objective-C枚举的Swift结构体 支持枚举数组跨语言使用

问题描述

需要编写的基础代码如下:

@objc(OCSomeEnum)
enum SomeEnum: Int {
  case c1
  case c2
  // 其余枚举成员
}

extension UnitySSPPlacementType { 
  // 仅Swift环境可用的扩展逻辑
}

需求是将该枚举的多个值组装为数组,作为类初始化方法的入参:

@objc(OCSomeClass)
class SomeClass: NSObject {
  @objc
  init(cases: [SomeEnum]) {
    // 初始化逻辑
  }
}

直接编写上述代码会触发桥接错误:@objc标记与参数类型[SomeEnum]存在兼容问题,Objective-C桥接机制仅支持识别单个SomeEnum枚举值,无法直接桥接Swift原生枚举数组类型。

现有公开的同类问题资料,仅说明了Objective-C与Swift间桥接传递单个枚举值的方法,没有覆盖跨语言传递多个枚举值的实现方案。

尝试参考苹果官方UIKit的UIViewAnimationOptions实现逻辑:Swift端该类型定义为struct AnimationOptions,Objective-C端对应为NSUInteger底层类型的枚举,但暂不清楚如何自定义可桥接为Objective-C枚举的Swift结构体类型。

解决方案

通过双初始化方法适配的方式即可实现两端兼容,代码如下:

@objc(OCSomeClass)
class SomeClass: NSObject {
  // 供Swift端调用的原生初始化方法,直接接收枚举数组
  init(cases: [SomeEnum]) { 
    // 核心初始化逻辑
  }

  // 暴露给Objective-C端调用的便利初始化方法,接收Int数组
  @objc
  convenience init(cases: [Int]) {
    let enumCases = cases.compactMap { SomeEnum(rawValue: $0) }
    self.init(cases: enumCases)
  }
}

实现逻辑说明:

  • 保留Swift原生的初始化方法,Swift侧调用时可以直接传入枚举数组,完整保留类型安全特性
  • 新增标记@objc的便利构造器,接收枚举底层RawValue类型Int组成的数组,Objective-C侧可直接传入枚举对应的整型值数组
  • 便利构造器内部将Int值转换为对应枚举实例,再调用原生初始化方法完成初始化流程
  • 建议使用compactMap做类型转换,替代强制解包写法,避免传入非法Int值时触发运行时崩溃

内容的提问来源于stack exchange,提问作者Вячеслав Герчиков

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:18:32