[英]Swift Tree Structure, encoding and accessing nodes
我無法弄清楚為什么以下不運行。 目標是創建一個具有引用類型的樹結構,可以將其保存到 json 文件中,但以下操場代碼無法運行。
根節點有一個 nil 父節點,但我認為編碼器忽略了 nil 值。 在我的應用程序中,我得到一個 EXC_BAD_ACCESS。 這是否需要用結構而不是類來完成,如果是這樣,有沒有辦法在不遍歷整個樹的情況下訪問特定節點? 任何幫助表示贊賞。
import Cocoa
final class Node: Codable {
var id: UUID
var data: [MyData]
var children: [Node]
var parent: Node? = nil
init() {
self.id = UUID()
self.data = []
self.children = []
}
func add(data: MyData) {
data.parent = self
self.data.append(data)
}
func add(child: Node) {
child.parent = self
self.children.append(child)
}
}
final class MyData: Codable {
var id: UUID
var label: String
var value: String
var parent: Node? = nil
init(label: String, value: String) {
self.id = UUID()
self.label = label
self.value = value
}
}
var root = Node()
root.add(data: MyData(label: "label 1", value: "value 1"))
root.add(data: MyData(label: "label 2", value: "value 2"))
var child = Node()
child.add(data: MyData(label: "label 3", value: "value 3"))
root.add(child: child)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let json = try encoder.encode(root)
print(String(data: json, encoding: .utf8)!)
問題是默認情況下Codable
嘗試編碼/解碼符合類型的所有屬性。 這意味着孩子嘗試編碼/解碼他們的父母,父母也包含孩子,因此導致無限循環。
您需要通過提供符合CodingKey
的類型來手動指定要編碼/解碼的屬性。 通過從Node.CodingKeys
和MyData.CodingKeys
中省略parent
屬性,您可以解決無限循環。
import Foundation
final class Node: Codable {
let id = UUID()
var data: [MyData]
var children: [Node]
var parent: Node? = nil
init() {
self.data = []
self.children = []
}
func add(data: MyData) {
data.parent = self
self.data.append(data)
}
func add(child: Node) {
child.parent = self
self.children.append(child)
}
private enum CodingKeys: String, CodingKey {
case data
case children
}
}
final class MyData: Codable {
let id = UUID()
var label: String
var value: String
var parent: Node? = nil
init(label: String, value: String) {
self.label = label
self.value = value
}
private enum CodingKeys: String, CodingKey {
case label
case value
}
}
var root = Node()
root.add(data: MyData(label: "label 1", value: "value 1"))
root.add(data: MyData(label: "label 2", value: "value 2"))
var child = Node()
child.add(data: MyData(label: "label 3", value: "value 3"))
root.add(child: child)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let json = try encoder.encode(root)
print(String(data: json, encoding: .utf8)!)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.