【问题标题】:Could not cast value of type 'Swift.__SwiftDeferredNSArray' (0x104cd8ae8) to 'NSMutableArray' (0x7fff87c52960)无法将“Swift.__SwiftDeferredNSArray”(0x104cd8ae8)类型的值转换为“NSMutableArray”(0x7fff87c52960)
【发布时间】:2020-01-27 06:12:22
【问题描述】:

下面的代码行产生了错误,

let response1 : NSMutableArray = NSMutableArray.init(array: (JSON.object as! NSMutableArray).value(forKey: "media_list") as! NSArray)

正如错误所说,我理解它是一个强制转换异常,但我无法修改代码以使其工作。我对 Swift 有点陌生,所以任何帮助都将不胜感激。 下面是我的 JSON.object

所以,我检查了一下,这是我的 JSON.object

[["offset": 30119146, "file_size": 30119146, "filename": video_220120201129271580.mp4, "mediaPath": file:///Users/evuser/Library/Developer/CoreSimulator/Devices/B9B0232F-237D-4413-BB81-BD5FAC727305/data/Containers/Data/Application/401D5D91-4500-434A-98FE-BD416135A1C7/Documents/video_220120201129271580.mp4, "status": completed, "group_id": fKQ2Xd9bE0cXchsw, "createdDate": 2020/01/22 13:59:47, "_id": 5e27e4d3138c8801cd3c26ca, "user_id": 21, "mime_type": video/mp4, "dest_path": /video_220120201129271580.mp4, "resource_id": 3a743d84-eafe-41e5-9f4c-dece67598c32], 
["offset": 6435018, "file_size": 6435018, "filename": video_220120201127525480.mp4, "mediaPath": file:///Users/evuser/Library/Developer/CoreSimulator/Devices/B9B0232F-237D-4413-BB81-BD5FAC727305/data/Containers/Data/Application/401D5D91-4500-434A-98FE-BD416135A1C7/Documents/video_220120201127525480.mp4, "status": completed, "group_id": ffoHuGL0Z17vOqY9, "createdDate": 2020/01/22 13:58:10, "_id": 5e27e472138c8801cd3c26c9, "user_id": 21, "mime_type": video/mp4, "dest_path": /video_220120201127525480.mp4, "resource_id": 50e34fd5-b488-4861-aedd-03ea1ed0d91c]]

【问题讨论】:

  • JSON.object 的类型是什么?
  • 首先,很少有理由在 Swift 中使用 NSArrayNSMutable 数组。您崩溃的原因是JSON.object 似乎是NSArray 而不是NSMutableArray。你的整行没有多大意义 - 你不能在 NSArray 上使用 value(forKey:) - 这是在 NSDictionary 上使用的 - 你也不应该在 Swift 中使用它。 JSON 的最佳方法是使用 Codable 并创建适当的结构

标签: ios swift iphone nsmutablearray nsarray


【解决方案1】:

看来JSON.object 可能不是数组。或者至少不是可变数组。如果不查看JSON.object,我们将很难确定您的问题。快速修复实际上可能是

let response1 : NSMutableArray = NSMutableArray.init(array: (JSON.object as! NSArray).value(forKey: "media_list") as! NSArray)

但我会尝试进一步挖掘。尝试检查到底发生了什么,并尽量避免使用旧的 Objective-C Next Step (NS) 对象。一步一步做:

let response1: [Any]? = {
    guard let mainArray = JSON.object as? [Any] else {
        print("Outer object is not an array. Check type of \(JSON.object)")
        return nil
    }
    var mutableVersionOfArray = mainArray // This already creates a mutable copy because we used "var" instead of "let"
    guard let mediaList = mutableVersionOfArray.value(forKey: "media_list") as? [Any] else {
        print("Inner object is not an array. Check type of \(mutableVersionOfArray.value(forKey: "media_list"))")
        return nil
    }
    return mediaList    
}()

但这段代码对我来说毫无意义。查看您的代码,我希望您的 JSON 对象类似于:

{
    "media_list": [{}, {}]
}

在这种情况下,您正在查看字典。请尝试以下操作:

let mediaList: [Any]? = {
    guard let topDictionary = JSON.object as? [String: Any] else {
        print("Outer object is not a dictionary. Check type of \(JSON.object)")
        return nil
    }
    guard let mediaListItem = topDictionary["media_list"] else {
        print("There is no media_list in payload")
        return nil
    }
    guard let mediaList = mediaListItem as? [Any] else {
        print("mediaList is not an array")
        return nil
    }
    return mediaList
}

我希望你能看到数组和字典之间的区别。数组中有一些 N 有序元素,而字典中有键值对。因此,要访问键下的值,您将其称为dictionary[key]。如果您是正确的,您的整个代码可能只是:

let response1 = (JSON.object as? [String: Any])?["media_list"] as? [Any]

但是如果它返回 nil 可能会有点难以调试出了什么问题。

【讨论】:

  • 所以我检查了,我意识到我没有密钥“media_list”。所以我确实修改它让 response1 : NSMutableArray = NSMutableArray.init(array: (JSON.object as!NSArray) as NSArray) 并且我不再收到错误。
  • 非常感谢,这有助于我更好地理解不是字典而是数组的问题并解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-26
  • 1970-01-01
  • 2017-07-01
  • 2016-01-12
相关资源
最近更新 更多