【问题标题】:Cannot subscript a value of type '[NSObject : AnyObject]' with an index of type 'String'无法使用“String”类型的索引为“[NSObject : AnyObject]”类型的值下标
【发布时间】:2018-10-12 22:47:57
【问题描述】:

我在下面代码的 sn-p 上遇到错误。每次我尝试构建它时,编译器都会抱怨:

不能用“String”类型的索引为“[NSObject : AnyObject]”类型的值下标

代码如下:

import Foundation
import MapKit

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

extension MKPointAnnotation {
    var propertyState: [NSObject: AnyObject] {
        get {
            return [ LocationKey.Longitude.rawValue as NSObject: NSNumber(value: coordinate.latitude),
                     LocationKey.Longitude.rawValue as NSObject: NSNumber(value: coordinate.longitude),
                     LocationKey.Title.rawValue as NSObject: title as AnyObject]
        }
        set {
            let lat = (newValue[LocationKey.Latitude.rawValue] as NSNumber).doubleValue
            let long = (newValue[LocationKey.Longitude.rawValue] as NSNumber).doubleValue
            coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
            title = newValue[LocationKey.Title.rawValue] as NSString
        }
    }
}

我真正遇到问题的代码行是:

let lat = (newValue[LocationKey.Latitude.rawValue] as NSNumber).doubleValue
let long = (newValue[LocationKey.Longitude.rawValue] as NSNumber).doubleValue
title = newValue[LocationKey.Title.rawValue] as NSString

非常感谢!

【问题讨论】:

标签: ios swift xcode dictionary mapkit


【解决方案1】:

您的代码太复杂了。所有值都是值类型,所以将字典声明为[String:Any]——顺便解决了错误——并摆脱了所有丑陋的类型转换为NSNumberAnyObject

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.latitude.rawValue: coordinate.latitude,
                     LocationKey.longitude.rawValue: coordinate.longitude,
                     LocationKey.title.rawValue: title ?? ""]
        }
        set {
            guard let lat = newValue[LocationKey.latitude.rawValue] as? CLLocationDegrees,
            let long = newValue[LocationKey.longitude.rawValue] as? CLLocationDegrees else { return }
            coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
            title = newValue[LocationKey.title.rawValue] as? String
        }
    }
}

你甚至可以使用枚举作为键

extension MKPointAnnotation {
    var propertyState: [LocationKey: Any] {
        get {
            return [ .latitude: coordinate.latitude,
                     .longitude: coordinate.longitude,
                     .title: title ?? ""]
        }
        set {
            guard let lat = newValue[.latitude] as? CLLocationDegrees,
            let long = newValue[.longitude] as? CLLocationDegrees else { return }
            coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
            title = newValue[.title] as? String
        }
    }
}

注意:您的 getter 使用了两次LocationKey.Longitude,这将导致编译器错误。

【讨论】:

    【解决方案2】:

    var propertyState: [NSObject: AnyObject] 是一个字典,其键类型为NSObject。尝试将其更改为输入 String 并查看是否有效。

    【讨论】:

      【解决方案3】:

      这是因为您正在使用 NSObject 键创建字典。

      试试这个:

      import Foundation
      import MapKit
      
      enum LocationKey: String {
          case Latitude = "lat"
          case Longitude = "long"
          case Title = "title"
      }
      
      extension MKPointAnnotation {
          var propertyState: [String: AnyObject] {
              get {
                  return [ LocationKey.Longitude.rawValue: NSNumber(value: coordinate.latitude),
                           LocationKey.Longitude.rawValue: NSNumber(value: coordinate.longitude),
                           LocationKey.Title.rawValue: title as AnyObject]
              }
              set {
                  guard let lat = (newValue[LocationKey.Latitude.rawValue] as? NSNumber)?.doubleValue,
                      let long = (newValue[LocationKey.Longitude.rawValue] as? NSNumber)?.doubleValue else {
                      return
                  }
                  coordinate = CLLocationCoordinate2D(latitude: lat, longitude: long)
                  title = newValue[LocationKey.Title.rawValue] as? String
              }
          }
      }
      

      在代码中,您已经在 properyState setter 中看到了 сonditionally unwrapped 选项,因为最好不要使用强制展开。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多