Swift报错:无法用NSKeyValueChangeKey下标访问[NSObject : AnyObject]类型值
解决Cannot subscript a value of type '[NSObject : AnyObject]' with an index of type 'NSKeyValueChangeKey'错误
这个报错很常见,本质是Swift严格的类型检查在“找茬”:你试图用NSKeyValueChangeKey枚举值作为下标,去访问一个key类型为NSObject的字典,两者类型不兼容,所以编译器直接报错了。
下面给你两种靠谱的修复方式:
方案一:类型安全的字典转换(推荐)
把Objective-C风格的[NSObject: AnyObject]字典转换成Swift原生的[NSKeyValueChangeKey: Any]类型,这样就能用枚举成员.newKey安全访问了:
func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutableRawPointer) { if !didFindMyLocation { // 安全转换字典类型并获取新值 guard let typedChange = change as? [NSKeyValueChangeKey: Any], let myLocation = typedChange[.newKey] as? CLLocation else { // 如果转换失败,直接返回,避免崩溃 return } viewMap.camera = GMSCameraPosition.camera(withTarget: myLocation.coordinate, zoom: 10.0) viewMap.settings.myLocationButton = true didFindMyLocation = true } }
这里用guard语句做安全转换,比强制解包更稳妥,能避免潜在的崩溃。
方案二:快速适配的字符串key方式
如果只是想快速修复旧代码,可以直接用NSKeyValueChangeNewKey对应的原始字符串"new"作为key,注意要把字符串转成NSString(因为字典的key是NSObject类型):
func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutableRawPointer) { if !didFindMyLocation { // 用NSString类型的字符串key访问字典 if let myLocation = change["new" as NSString] as? CLLocation { viewMap.camera = GMSCameraPosition.camera(withTarget: myLocation.coordinate, zoom: 10.0) viewMap.settings.myLocationButton = true didFindMyLocation = true } } }
小建议
如果你的项目使用的是Swift 4及以上版本,强烈建议切换到Swift原生的KVO API(比如observe(_:options:changeHandler:)),它完全基于Swift的类型系统,不需要处理Objective-C风格的字典,代码更简洁安全,也能从根源避免这类类型不匹配的问题。
内容的提问来源于stack exchange,提问作者Devil
相关产品推荐
相关产品推荐

