使用一个字典的键操作另一个字典时崩溃(Xcode 9.3 Playground)
解决Playground中字典扩展解包Optional的致命错误
问题还原
你在Xcode 9.3的Playground里编写字典扩展时遇到了崩溃,报错信息是Unexpectedly found nil while unwrapping an Optional value,崩溃卡在这行代码:
if (value as! String) != (dictionary[key] as! String) {
更费解的是,明明字典里存在x这个键,但dictionary[key]却返回了nil,直接触发了强制解包的致命错误。你的代码大致结构如下:
//: Playground - noun: a place where people can play import UIKit extension Dictionary { func isSubDictionary(of dictionary: [AnyHashable: Any]) -> Bool { var ...
问题根源分析
我之前在Playground里也碰到过类似的坑,大概率是这几个原因导致的:
- 键类型隐形不匹配:你原字典的键类型(比如
String)和传入的[AnyHashable: Any]字典的键类型可能不一致——比如后者的x键实际是NSString类型,用String类型的key去查询自然找不到对应值,返回nil。AnyHashable虽然能包装各种哈希类型,但匹配时是严格按类型校验的。 - Playground缓存/类型推断bug:老版本Playground偶尔会抽风,缓存的类型信息和实际代码逻辑不一致,导致明明逻辑正确却出现异常。
- 强制解包的固有风险:就算键的问题解决了,
value as! String和dictionary[key] as! String都是硬解包操作,只要值不是String类型,照样会崩溃,这本身就是不安全的写法。
一步步解决问题
1. 先替换强制解包为安全写法
这是最紧急的修复,先把崩溃的根源堵住,用可选绑定替代as!:
// 替换原来的报错行 guard let selfStringValue = value as? String, let dictValue = dictionary[key], let dictStringValue = dictValue as? String else { // 可根据你的业务逻辑处理:比如键不存在/类型不匹配时直接返回false return false } if selfStringValue != dictStringValue { return false }
2. 统一键类型,规避AnyHashable的坑
如果你的字典都是用String作为键,不如给扩展加上类型约束,从根源避免类型不匹配的问题:
extension Dictionary where Key == String, Value == Any { func isSubDictionary(of dictionary: [String: Any]) -> Bool { for (key, value) in self { // 使用上面的安全绑定写法 guard let selfStringValue = value as? String, let dictStringValue = dictionary[key] as? String else { return false } if selfStringValue != dictStringValue { return false } } return true } }
如果必须保留AnyHashable类型,访问时要把原键转成AnyHashable再查询:
guard let dictValue = dictionary[AnyHashable(key)] else { // 处理键不存在的情况 return false }
3. 清理Playground缓存
老版本Xcode的Playground经常有缓存异常问题,试试这几步:
- 关闭当前Playground后重新打开
- 点击Xcode顶部菜单的
Product > Clean Build Folder - 若还是不行,直接重启Xcode
测试验证
你可以用这段代码验证修复后的逻辑是否正常:
let subDict: [String: Any] = ["x": "hello"] let mainDict: [String: Any] = ["x": "hello", "y": "world"] print(subDict.isSubDictionary(of: mainDict)) // 预期输出true
内容的提问来源于stack exchange,提问作者Shashank
相关产品推荐
相关产品推荐

