将 NSNumber 数组转换为 Swift 枚举

Convert array of NSNumber to Swift enum

提问人:Rik 提问时间:11/9/2023 最后编辑:Rik 更新时间:11/11/2023 访问量:63

问:

我想从具有相同枚举值但在 Swift 中的 NSNumber 的 Objective-C 数组填充此函数。我想知道是否有 Swifty 方法可以做到这一点:

/// Objective-c
typedef NS_ENUM(uint32_t, PTYAction) {
  PTYActionBlockSpace
  PTYActionLeaveSpace
  PTYActionMuteSpace
  PTYActionUnmuteSpace
};

/// Swift
enum Action {
  case blockSpace
  case leaveSpace
  case muteSpace
  case unmuteSpace
}

func createAction(_ action:PTYAction) {
 switch action {
  case .blockSpace:
    return .blockSpace
  case .leaveSpace
    return .leaveSpace
  case .muteSpace
    return .muteSpace
  case .unmuteSpace
    return .unmuteSpace
  }
}

func createActions(_ actions: [NSNumber]) -> [Action] {
  // Populate this function.
}
数组 swift 枚举

评论

0赞 lorem ipsum 11/9/2023
枚举必须有一个匹配的 RawRepresentable,只需在冒号后添加正确的类型,然后就可以使用 rawValue
0赞 Sweeper 11/9/2023
所以 0 表示和 1 表示等?blockSpaceleaveSpace
0赞 Rik 11/9/2023
@Sweeper是的,这应该是正确的

答:

1赞 son 11/9/2023 #1

您的枚举应该具有表示 NSNumber 值的具体类型,即 Integer。

enum Action: UInt32 {
  case blockSpace  // 0
  case leaveSpace  // 1
  case muteSpace   // 2
  case unmuteSpace // 3

  var objcEnum: DYNAction {
    switch self {
      case .blockSpace:
        return .blockSpace
      case .leaveSpace:
        return .leaveSpace
      case .muteSpace:
        return .muteSpace
      case .unmuteSpace:
        return .unmuteSpace
    }
  }
}

func createActions(_ actions: [NSNumber]) -> [Action] {
    actions.compactMap { Action(rawValue: $0.uint32Value) 
}

func createAction(_ actions: [DYNAction]) -> [Action] {
    actions.compactMap { Action(rawValue: $0.rawValue) }
}

评论

0赞 Rik 11/9/2023
谢谢你的回答。我编辑了问题以包含 objective-c。我认为这个答案会起作用,但如果在目标 c 中添加了枚举值,它可能会很脆弱,它可能会导致错误。我应该从一开始就把目标c放在那里。我想我可以弄清楚如何以某种方式使用原始值......我会让你编辑它,如果没有,我会添加一个答案......
0赞 son 11/9/2023
@Rik我可以看到您的 obj-c 枚举类型是 uint32,那么为什么要将其直接从 obj-c 枚举转换为具有该 rawValue 的 swift 枚举呢?
0赞 son 11/9/2023
如果需要,Swift 枚举可以包含一个属性,该属性有助于转换回 objc-c 枚举。
0赞 Rik 11/11/2023 #2
 func createActions(_ actions: [NSNumber]) -> [Action] {
    var returnVal = [Action]()
    for item in actions {
      let action = PTYAction(rawValue: item.uint32Value)
      switch action {
      case .blockSpace:
        returnVal.append(action.blockSpace)
      case .leaveSpace:
        returnVal.append(action.leaveSpace)
      case .muteSpace:
        returnVal.append(action.muteSpace)
      case .unmuteSpace:
        returnVal.append(action.unmuteSpace)
      case .none:
        continue
      }
    }
    return retVal
  }