繁体   English   中英

在尝试从类对象数组中读取值时,收到“致命错误:NSArray元素无法匹配Swift数组元素类型”

[英]getting “fatal error: NSArray element failed to match the Swift Array Element type” when trying to read values from an array of class objects

有一个问题,我无法理解,也无法找到答案:我在tableViewCOntroller中有这个方法,它在其中调用另一个带有TableView的viewCOntroller

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "ShowBook" {
        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            let books = categoryStore.allCategories[selectedIndexPath.row].books

            let destinationVC = segue.destinationViewController as! BookViewController
            destinationVC.books = books
        }
    }
}

然后在BookViewController我有这个只是为了测试:

var books = [Book]()

override func viewDidLoad() {
    super.viewDidLoad()

    print(books[0].name)
}

我可以看到books var是一个拿着书的数组:

class Book {
var name: String = ""
var id: Int = -1
var categoryId: Int = -1
var bookAuthor: String = ""
var level1Name: String = ""
var level2Name: String = ""
var level3Name: String = ""
var level4Name: String = ""
var levels: Int = -1
var orderKey: Int = -1
var viewCount: Int = -1
var viewLevel: Int = -1
var chapters: [AnyObject] = []

}

所以我在books var中获得了一系列包含13个键/值对字典的书籍

当我试图打印任何东西时,让我们说:

print(books[0].name)

我收到错误:

致命错误:NSArray元素无法匹配Swift数组元素类型

我无法理解为什么......

ps过渡是有效的,我可以看到下一个表,但后来得到了致命的错误

在此输入图像描述

好吧,让我们从你的错误开始吧。

致命错误:NSArray元素无法匹配Swift数组元素类型

一个快速阵列抱怨其中一个元素不是它所期望的。 NSArray元素与swift数组元素不匹配。

现在我们知道NSArray可以存储不同类型的元素,例如,NSNumber,NSDictionary,NSString ......你得到了图片。 很明显,我们这里的问题与类型有关。

现在看看你的segue代码我们可以看到我们实际上并没有说明什么类型的书籍,我们让swift的类型推断为我们解决。 这是我们问题的第一个迹象。 你期待一个[Book]数组,但由于某种原因你得到了一种NSArray。

如果您从以下位置进行更改:

let books = categoryStore.allCategories[selectedIndexPath.row].books
let books : [Book] = categoryStore.allCategories[selectedIndexPath.row].books

您现在将在此行崩溃,因为您现在正在说明预期的类型。

完整方法:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "ShowBook" {
        if let selectedIndexPath = tableView.indexPathForSelectedRow {
            let books : [Book] = categoryStore.allCategories[selectedIndexPath.row].books

            let destinationVC = segue.destinationViewController as! BookViewController
            destinationVC.books = books
        }
    }
}

这由调试器控制台输出支持,它表示您有13个NSDictionary类型的数组

这意味着您需要调查填充[Book]数组的位置 - 即categoryStore.allCategories

好的,这是一个可能对其他人有帮助的初学者问题。

场景:我有一个复杂的JSON:root是对象,对象中的每个键都有一个数值(不同的键,但值具有相同的结构),值是Category对象! 对于每个类别,有许多键/值对,其中一个是Books KEY,值是数组或对象,每个都是一本书。

问题是:当我对JSON进行反序列化时,我使用一系列书籍解析了这些类别,但是注释中提到的书籍并不是真正的书籍实例,而是更多的NSDictionary对象数组。

因此,在反序列化之后,我必须在Book类中添加一个init方法来获取NSDictionary并将其解析为Book对象。

在每个类别之后,我必须查看NSArray的书籍,并为每一个创建一个Object go Book并返回一个书籍阵列。

这就行了,现在每件事都有效:

API:

// Getting NSArray of NSDictionary that represnets books and convert it into Books array
static func getBooksFromArr(booksArr: NSArray) -> [Book] {
    var books = [Book]()

    for book in booksArr {
        let thisBook = Book(bookDict: book as! NSDictionary)
        books.append(thisBook)
        print(book)
    }

    return books
}

// Parsing the category object
private static func CategoryFromJSONObject(json: [String: AnyObject]) -> Category? {
    guard let
        id = json["Id"] as? Int,
        name = json["Name"] as? String,
        booksArr = json["Books"] as? NSArray else {
            return nil
    }

    let books = getBooksFromArr(booksArr)

    return Category(name: name, id: id, books: books)
}

书类:

init(bookDict: NSDictionary){
    self.name = (bookDict["Name"] ?? "") as! String
    self.id = (bookDict["Id"] ?? -1) as! Int
    self.categoryId = (bookDict["CategoryId"] ?? -1) as! Int
    self.bookAuthor = (bookDict["BookAuthor"] ?? "") as! String
    self.level1Name = (bookDict["Level1Name"] ?? "") as! String
    self.level2Name = (bookDict["Level2Name"] ?? "") as! String
    self.level3Name = (bookDict["Level3Name"] ?? "") as! String
    self.level4Name = (bookDict["Level4Name"] ?? "") as! String
    self.levels = (bookDict["Levels"] ?? -1) as! Int
    self.orderKey = (bookDict["OrderKey"] ?? -1) as! Int
    self.viewCount = (bookDict["ViewCount"] ?? -1) as! Int
    self.viewLevel = (bookDict["ViewLevel"] ?? -1) as! Int
    self.chapters = (bookDict["Chapters"] ?? []) as! [AnyObject]
}

如果我想撰写书籍来掌握章节,我现在必须为章节做同样的事情。

我没有写REST API,所以不要问我为什么这样做,但现在每件事都有效,这就是它的重点。

在我的情况下,它只是在问题上面的代码中转换为错误的数组类型...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM