【问题标题】:Could not cast value of type '__NSDictionaryI' to 'NSMutableDictionary'无法将“__NSDictionaryI”类型的值转换为“NSMutableDictionary”
【发布时间】:2021-05-13 11:01:28
【问题描述】:

我最近开始使用 swift。我正在使用下面的代码将字符串转换为 nsmutabledictionary。

print(response);
let responseData = response.data(using: .utf8)!
var json: NSMutableDictionary = try JSONSerialization.jsonObject(with: responseData, options: []) as! NSMutableDictionary;

服务器对请求的响应如下。

{"token1":"blah.blah.blah","token_type":"smarty","expires_in":1209600,"token2":"blah.blah.blah"}

我被困在这里。请帮忙。

【问题讨论】:

  • 分享一些你尝试过的代码以及它给你错误的地方。
  • 不要在 Swift 中使用 JSONSerialization。请改用CodableJSONDecoder。见this问答。您也可以使用quicktype为您自动生成解析代码。
  • var json = try JSONSerialization.jsonObject(with: responseData, options: []) as? [String: Any] 获取可变的原生 swift 字典
  • 感谢@JoakimDanielson 成功了。虽然我不明白为什么这种方法失败了。 NSMutableDictionary 和 [String:Any] 有什么区别
  • 因为JSONSerialization.jsonObject(with: responseData, options: [])NSDictionary,而不是NSMutableDictionary,所以它不是可变的,这就是原因。使用 Swift Dictionary 是不同的。

标签: swift nsmutabledictionary


【解决方案1】:

这并不奇怪,因为它与 Objective-C 中的行为完全相同。

在 ObjC 中,您不能将不可变类型强制转换为可变类型。运行这段代码

NSDictionary *dict = @{@"Foo":@"1"};
NSMutableDictionary *mutableDict = (NSMutableDictionary *)dict;
[mutableDict setObject:@"2" forKey: @"Bar"];

引发异常

-[__NSSingleEntryDictionaryI setObject:forKey:]: 无法识别的选择器发送到实例

因为类型保持不变。你必须创建一个新的NSMutableDictionary 实例

NSMutableDictionary *mutableDict = [NSMutableDictionary dictionaryWithDictionary:dict];

具有讽刺意味的是——我仍然在谈论 ObjC——以防NSJSONSerialization 出现著名的选项.mutableContainers。使用此选项,您可以直接创建可变数组/字典,请注意,仅在 Objective-C 中。

另一方面,在 Swift 中,此选项毫无意义,因为 Swift Dictionary / ArrayNSMutable... 对应项彼此不相关,在 Swift 中,您可以简单地使(本机)类型可变使用 var 关键字。

所以写

var json = try JSONSerialization.jsonObject(with: responseData) as! [String:Any]

底线是:

不要在 Swift 中使用 NSMutable... 集合类型。

【讨论】:

    【解决方案2】:

    jsonObject(with:options:)返回Any,你可以试试:

    let response = """
        {"token1":"blah.blah.blah","token_type":"smarty","expires_in":1209600,"token2":"blah.blah.blah"}
    """
    let responseData = response.data(using: .utf8)!
    let json = try JSONSerialization.jsonObject(with: responseData, options: []) as! [String: Any]
    let mutableDictionary = NSMutableDictionary(dictionary: json)
    
    

    【讨论】:

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