枚举在不应该被初始化时被初始化

时间:2019-02-01 17:12:14

标签: ios swift

我正试图为从称为OpenTok的实时流框架返回的错误创建管理器。出于某种原因,代表OpenTok错误枚举被初始化时,他们不应该。例如:

let error = OTSubscriberErrorCode(rawValue: 1010)
// The rawValue is an Int32, I don't know if that makes a difference

此成功地初始化的OTSubscriberErrorCode,但是,1010不是OTSubscriberErrorCode,它是一个OTPublisherErrorCode,专门为情况下,错误代码sessionDisconnected

See hereOTSubscriberErrorCode的文档。

See hereOTPublisherErrorCode的文档。

error应该是nil,但不是。为什么会这样?

2 个答案:

答案 0 :(得分:2)

Apple在“Grouping Related Objective-C Constants”中解释了此行为:

  

枚举使用NS_ENUM宏时初始化一个与原始值不对应于枚举的情况下也不会失败导入。与C此特性功能有助于兼容性,这允许任何值将被存储在一个枚举,包括在内部使用,但在头没有暴露值。

答案 1 :(得分:1)

OTSubscriberErrorCode 是用Objective-C编写的NS_ENUM。 (Why objective-c NS_ENUM variable automatically have default value

typedef NS_ENUM(int32_t, OTSubscriberErrorCode ) {
   OTSubscriberSuccess = 0,
   OTConnectionTimedOut = 1542,
   OTSubscriberSessionDisconnected = 1541,
   OTSubscriberWebRTCError = 1600,
   OTSubscriberServerCannotFindStream = 1604,
   OTSubscriberStreamLimitExceeded = 1605,
   OTSubscriberInternalError = 2000,
};

您可以像这样创建该枚举的Swift版本:

enum OTSubscriberErrorCodeSwift: Int32 {
    case success = 0
    case timeout = 1542
    case sessionDisconnected = 1541
    case webRTCError = 1600
    case cannotFindStream = 1604
    case streamLimitExceeded = 1605
    case internalError = 2000
}

因此,当您尝试使用无效的rawValue从“ Swifty”枚举中出错时,您将得到nil。

let error = OTSubscriberErrorCodeSwift(rawValue: 1010) // nil

编辑

使用Objective-C的NS_ENUM时,您可以只使用switch语句,如下所示:

let error = OTSubscriberErrorCode(rawValue: 1010)
        if let error = error {
            switch error {
            case .subscriberSuccess: print("subscriberSuccess")
            case .connectionTimedOut: print("timeout")
            case .subscriberSessionDisconnected: print("subscriberSessionDisconnected")
            case .subscriberWebRTCError: print("subscriberWebRTCError")
            case .subscriberServerCannotFindStream: print("subscriberServerCannotFindStream")
            case .subscriberStreamLimitExceeded: print("subscriberStreamLimitExceeded")
            case .subscriberInternalError: print("subscriberInternalError")
            default: print("NO ERROR")
            }
        }

在上述情况下,您将使用默认设置。从那里开始,做任何您想做的事情,就好像error变量为nil。