[英]Codable class does not conform to protocol Decodable
為什么我會收到“類型‘書簽’不符合協議‘可解碼’”錯誤消息?
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
}
init(publication: Publication?, indexPath: [Int]) {
self.publication = publication
self.indexPath = indexPath
}
}
我不想保存出版物變量,因為出版物擁有書簽,但書簽需要知道它屬於哪個出版物。 Publication 的 decode init 會將書簽引用設置為自身。
由於weak
引用,編譯器無法合成所需的init(from:)
方法,需要自己編寫。
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
private enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
}
init(publication: Publication?, indexPath: [Int]) {
self.publication = publication
self.indexPath = indexPath
}
required init(from decoder:Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
indexPath = try values.decode([Int].self, forKey: .indexPath)
locationInText = try values.decode(Int.self, forKey: .locationInText)
}
}
為什么我收到“類型‘書簽’不符合‘可解碼’協議”的錯誤消息
這是因為出版不可解碼(你還沒有表現出它是什么,所以這是很難說),或者因為的weak
上指定publication
。
無論哪種方式,修復都很容易:您只需要實現init(from:)
即可完成 Decodable 的實現; 編譯器只是告訴你這個實現不能被綜合。
您可能會收到此消息的另一個原因是您的 CodingKeys 枚舉不是詳盡無遺的。 如果您在數據類型中有三個屬性,那么您的 CodingKeys 枚舉也需要有三個屬性/名稱案例。
僅僅因為您的 CodingKeys 枚舉不是詳盡無遺的,將publication
屬性添加到枚舉以實現這一點。
試試這個:
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
// All your properties should be included
enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
case publication // this one was missing
}
}
您不再需要 init 方法,因為現在可以合成實現。
簡而言之,在實現 Codable 時,所有非原始數據類型(平均類類型或可能是 Objective-c 類)的屬性都必須是 Codable。
weak var publication: Publication?
在這種情況下,發布是類類型,因此發布必須已實現 Codable
您可以省略編碼鍵枚舉中的屬性,前提是它具有默認值。
來自蘋果文檔
如果在解碼實例時不存在這些屬性,或者某些屬性不應包含在編碼表示中,則忽略 CodingKeys 枚舉中的屬性。 CodingKeys 中省略的屬性需要一個默認值,以便其包含的類型自動符合 Decodable 或 Codable。
有點愚蠢,但以防萬一它對其他人有幫助。 我收到這個錯誤是因為我把enum CodingKeys: CodingKeys
而不是enum CodingKeys: CodingKey
。
我有一個類似的問題,我偶然發現了這個修復程序。 由於我是 Swift 的新手,我不確定它為什么有效! 如果有人知道,我將不勝感激。
我改變了這個:
let id, type: Int
對此:
let id: Int
let type: Int
我可以通過將結構名稱更改為我想要的結構的當前swift文件來解決此問題。 例如,我要將其放入BookmarkModel.swift
,因此鍵入以下內容:
class Bookmark: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
}
init(publication: Publication?, indexPath: [Int]) {
self.publication = publication
self.indexPath = indexPath
}
}
更改為此:
class BookmarkModel: Codable {
weak var publication: Publication?
var indexPath: [Int]
var locationInText = 0
enum CodingKeys: String, CodingKey {
case indexPath
case locationInText
}
init(publication: Publication?, indexPath: [Int]) {
self.publication = publication
self.indexPath = indexPath
}
}
如果您已經嘗試了上述所有解決方案但仍然無法修復錯誤,那么我認為這可能是因為您用於數據 class 字段的數據類型。
在問題中,他們使用了 1 個字段weak var publication: Publication?
,並且如果您具有相同類型的 class 結構,那么也許您應該檢查該Publication
數據 class 是否符合Codable
class。
因為對於孩子 class 也必須遵守相同的協議,因為 tit 的字段也應該是可編碼和可去除的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.