Objective-C中NSNotification的userInfo转NSEnum失败问题排查
问题分析与解决方案
你遇到的这个问题,核心原因是Objective-C和Swift对枚举与NSNumber的桥接处理逻辑不一样,导致你在OC里的类型转换方式错误了。
为什么Objective-C里会得到错误的数值?
在Swift中,当你写userInfo?["status"] as? otaUpgradeStatus时,Swift会自动处理NSNumber到枚举类型的桥接——因为你的otaUpgradeStatus是基于NSUInteger的枚举,Swift会把后台传过来的NSNumber对象自动提取出它的数值,再映射到对应的枚举case。
但在Objective-C里,你直接写(otaUpgradeStatus)userInfo[@"status"],本质上是把NSNumber对象的内存地址强制转换成了otaUpgradeStatus类型(因为userInfo里存的是NSNumber对象,不是原始的NSUInteger数值)。你看到的6178538944其实就是这个NSNumber对象在内存中的地址值,自然和你的枚举值对不上,switch语句也就失效了。
正确的Objective-C写法
你需要先把userInfo里的value转换成NSNumber,再提取它的无符号整数值,最后转成枚举类型:
-(void)updateOTAStatus:(NSNotification *)notification { NSDictionary *userInfo = notification.userInfo; NSNumber *statusNum = userInfo[@"status"]; // 先判断是否为NSNumber,避免空值或类型错误导致崩溃 if ([statusNum isKindOfClass:[NSNumber class]]) { otaUpgradeStatus status = (otaUpgradeStatus)[statusNum unsignedIntegerValue]; // 这里再写你的switch逻辑就正常了 switch (status) { case none: // do something break; case started: // do something break; // ...其他case default: break; } } }
额外注意点
- 一定要加类型判断
[statusNum isKindOfClass:[NSNumber class]],避免后台传错类型或者字段缺失时,强制转换导致崩溃。 - 如果你的枚举是基于有符号整数(比如NSInteger),就用
integerValue而不是unsignedIntegerValue。
内容的提问来源于stack exchange,提问作者Hans
相关产品推荐
相关产品推荐

