macOS Monterey arm64编译NSKeyedUnarchiver反序列化告警问题求助
macOS Monterey arm64 架构NSKeyedUnarchiver告警问题解答
触发原因
- 该告警是macOS 12 Monterey针对arm64架构的系统级bug,和开发者本身的代码逻辑无关。
- 底层原因是NSKeyedUnarchiver的安全校验逻辑存在缺陷:当开发者指定允许解档的类为
NSDictionary时,系统本应自动放行NSDictionary内部嵌套的基础plist类型(包括NSString、NSNumber、NSArray等),但arm64架构下的Monterey运行时未正确实现该规则,导致解档嵌套基础类型时误触发告警。 - 该问题仅出现在arm64原生构建的应用中,x86_64架构通过Rosetta转译运行的应用不会触发。
告警消除方案
- 方案1:补充解档允许类列表
如果是自有代码调用了NSKeyedUnarchiver相关接口,只需要在声明允许类的集合时,把用到的所有嵌套基础类都加入集合即可,示例代码如下:
// 原允许类集合 // NSSet *allowedClasses = [NSSet setWithObject:[NSDictionary class]]; // 修改后的允许类集合,补充所有可能用到的嵌套基础plist类型 NSSet *allowedClasses = [NSSet setWithObjects: [NSDictionary class], [NSString class], [NSNumber class], [NSArray class], [NSDate class], [NSData class], nil]; NSError *error = nil; id unarchivedObj = [NSKeyedUnarchiver unarchiveObjectWithData:yourData allowingClasses:allowedClasses error:&error];
- 方案2:升级系统适配版本
苹果已经在macOS 13 Ventura及后续版本修复了该bug,如果你的应用最低支持版本可以升级到macOS 13及以上,无需修改代码即可自动消除该告警。 - 方案3:临时屏蔽控制台输出(不推荐)
如果告警是调用系统内部逻辑触发、你无法修改解档逻辑,也可以临时屏蔽该类系统日志:在Xcode的Scheme设置中,进入Run - Arguments - Environment Variables,添加变量OS_ACTIVITY_MODE,值设为disable即可。注意该方案会屏蔽所有系统级日志输出,仅建议本地调试时使用。
注:当前版本的告警仅为提前提醒,不会影响应用的正常运行,仅在后续新系统版本中才会禁止未声明类的解档操作,建议提前按方案1调整代码适配。
内容的提问来源于stack exchange,提问作者Pat_Morita
相关产品推荐
相关产品推荐

