如何在NSUserDefaults中存储可选布尔值以区分三种状态?
解决NSUserDefaults中区分未设置/True/False布尔状态的问题
嘿,这个问题我之前也碰到过!NSUserDefaults的bool(forKey:)方法确实会把未设置的键默认返回false,没法区分“没设置”和“明确设为false”的情况。不用枚举完全没问题,其实换个存储方式就行——用NSNumber来包装布尔值,因为它是对象类型,能完美支持nil状态。
具体实现步骤
存储逻辑:
当用户明确设置true/false时,把布尔值包装成NSNumber存入;要回到“未设置”状态时,直接移除对应键即可:// 明确设置为true UserDefaults.standard.set(NSNumber(value: true), forKey: "MyOptionalBoolKey") // 明确设置为false UserDefaults.standard.set(NSNumber(value: false), forKey: "MyOptionalBoolKey") // 重置为“未设置”状态 UserDefaults.standard.removeObject(forKey: "MyOptionalBoolKey")读取逻辑:
用object(forKey:)方法读取(这个方法会返回Any?,未设置时就是nil),再转成NSNumber?,就能区分三种状态了:let storedValue = UserDefaults.standard.object(forKey: "MyOptionalBoolKey") as? NSNumber switch storedValue { case .some(let number): let boolValue = number.boolValue print("已明确设置为:\(boolValue)") case .none: print("尚未设置") }也可以用更简洁的可选绑定写法:
if let boolNumber = UserDefaults.standard.object(forKey: "MyOptionalBoolKey") as? NSNumber { let isEnabled = boolNumber.boolValue // 处理已设置的true/false场景 } else { // 处理未设置的nil场景 }
为什么这个方法可行?
Swift的Bool是值类型,直接用set(_:forKey:)存Bool时,系统会自动转成NSNumber,但用bool(forKey:)读取时会直接拆包并返回默认值false,丢失了“键不存在”的状态。而用object(forKey:)读取的是原始对象,能完整保留“存在/不存在”的信息,完美对应你要的三种状态。
内容的提问来源于stack exchange,提问作者David Pilkington
相关产品推荐
相关产品推荐

