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

编译报错:无法用String类型下标访问[NSObject : AnyObject]类型值

解决Cannot subscript a value of type '[NSObject : AnyObject]' with an index of type 'String'错误

这个报错的核心原因很直白:你用了类型不匹配的字典下标。你定义的propertyState字典键类型是NSObject,但你用来下标访问的LocationKey.rawValue是Swift原生的String——虽然Swift的String能桥接到NSString(NSObject的子类),但编译器不会自动帮你做这个转换来适配下标操作,所以就抛出了类型不匹配的错误。

下面给你两种靠谱的修复方案,按需选择:

方案1:改用Swift风格的字典类型(推荐)

既然你的枚举是基于String的,完全没必要死守[NSObject: AnyObject]这种OC风格的字典。把propertyState的类型改成[String: Any](Swift 3+更推荐用Any代替AnyObject,除非你必须和纯OC代码交互),这样用String下标就完全顺理成章了:

import Foundation
import MapKit

enum LocationKey: String {
    case Latitude = "lat"
    case Longitude = "long"
    case Title = "title"
}

extension MKPointAnnotation {
    var propertyState: [String: Any] {
        get {
            return [
                LocationKey.Longitude.rawValue: coordinate.longitude as NSNumber,
                LocationKey.Latitude.rawValue: coordinate.latitude as NSNumber,
                LocationKey.Title.rawValue: title as Any
            ]
        }
        set {
            // 如果需要setter,也对应调整类型
            if let lat = newValue[LocationKey.Latitude.rawValue] as? Double {
                coordinate = CLLocationCoordinate2D(latitude: lat, longitude: coordinate.longitude)
            }
            if let lon = newValue[LocationKey.Longitude.rawValue] as? Double {
                coordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: lon)
            }
            title = newValue[LocationKey.Title.rawValue] as? String
        }
    }
}

方案2:保留OC风格字典,手动转换键类型

如果因为业务必须保留[NSObject: AnyObject]类型(比如要给老OC代码传参),那每次用下标时,把Swift String转换成NSString(NSObject的子类)即可:

取值时转换

// 示例:从propertyState中取经度
if let longitude = propertyState[LocationKey.Longitude.rawValue as NSString] as? Double {
    // 处理你的业务逻辑
}

或者在getter里直接用NSString作为键

extension MKPointAnnotation {
    var propertyState: [NSObject: AnyObject] {
        get {
            return [
                LocationKey.Longitude.rawValue as NSString: coordinate.longitude as NSObject,
                LocationKey.Latitude.rawValue as NSString: coordinate.latitude as NSObject,
                LocationKey.Title.rawValue as NSString: title as AnyObject? ?? NSNull()
            ]
        }
        // setter同理,用NSString作为下标访问newValue
        set {
            if let lat = newValue[LocationKey.Latitude.rawValue as NSString] as? Double {
                coordinate = CLLocationCoordinate2D(latitude: lat, longitude: coordinate.longitude)
            }
            // 其他属性的处理逻辑
        }
    }
}

额外提醒:Swift 3之后,AnyObject仅用于表示OC对象,Swift原生类型(比如String、Int)并不属于AnyObject范畴,所以用Any会更灵活,能兼容更多类型场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:28:47