【问题标题】:Converting NSEnum from Userinfo in NSNotification fails in Objective c在目标 c 中从 NSNotification 中的 Userinfo 转换 NSEnum 失败
【发布时间】:2018-01-25 15:20:54
【问题描述】:

我想将 userInfo 数据从 NSNotification 转换为枚举以在 switch 语句中使用。通知来自预编译的 c++ 框架,其中一些头文件定义了枚举。

-(void)updateOTAStatus:(NSNotification *)notification {
  NSDictionary *userInfo = notification.userInfo;
  otaUpgradeStatus status = (otaUpgradeStatus)userInfo[@"status"];
  //...
}

枚举定义:

typedef NS_ENUM(NSUInteger, otaUpgradeStatus) {
  none = 0,
  started = 1,
  inProgress = 2,
  completed = 3,
  failed = 4,
  failedLowBattery = 5,
  cancelled = 6,
  timedout = 7,
  forced = 8
};

调试时我得到了

Printing description of status:
(otaUpgradeStatus) status = 6178538944

当我在 Swift 中执行相同操作时,switch 语句失败:

let status = notification.userInfo?["status"] as? otaUpgradeStatus

我得到了正确的状态,switch语句按预期工作。

这里出了什么问题?

【问题讨论】:

  • 我的猜测是状态在字典中存储为NSNumber。试试NSNumber *num = userInfo[@"status"]; NSInteger status = num.integerValue;
  • 然后我得到 -[_SwiftValue integerValue]: unrecognized selector sent to instance 0x174452420,这可能是因为通知是从 swift 触发的,然后转到 c++ 库,然后转到目标 c 模块。我可以在堆栈跟踪中看到这一点。
  • 您是否创建通知?在这种情况下,将状态作为NSNumber 添加到信息字典中应该会有所帮助。
  • 类似userInfo: ["status": NSNumber(value: otaUpgradeStatus.failed.rawValue)]
  • 天哪,谢谢!有效!

标签: c++ objective-c swift enums


【解决方案1】:

NSDictionary 只能保存 对象,NSObject(的子类)的实例。 Swift 有一种机制可以在 不透明 _SwiftValue 实例透明。

但是为了与 Objective-C 的互操作性,您必须输入数字 作为 NSNumber 实例到 Swift 端的用户信息字典中,例如

let notification = Notification(name: ..., object: ...,
         userInfo: ["status":  NSNumber(value: otaUpgradeStatus.failed.rawValue)])

并在 Objective-C 端提取整数值,例如

NSDictionary *userInfo = notification.userInfo;
NSNumber *num = userInfo[@"status"];
otaUpgradeStatus status = num.unsignedIntegerValue;

【讨论】:

    猜你喜欢
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 2014-04-10
    • 2013-08-20
    • 2012-03-30
    相关资源
    最近更新 更多