You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中UserDefaults将Any转为Bool/Int:如何区分1/0与布尔值?

解决UserDefaults中Bool与Int类型混淆的问题

问题的核心原因是UserDefaults底层基于Objective-C实现,Swift的Bool和Int都会被装箱成NSNumber存储。当用value(forKey:)取值时,Swift会优先将NSNumber桥接为Int,导致原本存储的Bool被识别成1或0,无法直接通过as Bool匹配。

解决方案:通过NSNumber的类型元数据区分原始类型

不要用value(forKey:),改用object(forKey:)获取原始对象,然后检查NSNumber的objCType属性——这个属性会保留值的原始类型信息,能准确区分是从Bool转来的NSNumber还是原生Int转来的。

示例代码:

let rawValue = UserDefaults.standard.object(forKey: key)

switch rawValue {
case let number as NSNumber:
    // 判断是否为原始Bool类型
    if strcmp(number.objCType, @encode(Bool)) == 0 {
        return bool(number.boolValue)
    }
    // 判断是否为原始Int类型
    else if strcmp(number.objCType, @encode(Int)) == 0 {
        return int(number.intValue)
    }
    // 可扩展处理其他数值类型(如Float、Double)
case let value as Bool:
    // 兜底处理直接存储的Swift Bool(极少出现)
    return bool(value)
case let value as Int:
    // 兜底处理直接存储的Swift Int(极少出现)
    return int(value)
default:
    // 处理非数值类型或不存在的key
    break
}

补充说明

  • 存值时尽量使用UserDefaults的类型专属方法,比如set(true, forKey: "isEnabled"),这样取值时用bool(forKey:)可以直接拿到正确的Bool值,从根源避免类型混淆。
  • 如果是历史遗留的混合存储场景,上面的objCType判断是最可靠的区分方式,不会把实际存储的Int 1误判为true,也不会把Bool true误判为Int 1。

内容的提问来源于stack exchange,提问作者Evgeniy Kleban

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:25:01