You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift自定义队列类Codable编码后解码头尾引用失效问题求解

问题根因

Swift 的 JSONEncoder/JSONDecoder 采用按值递归序列化策略,本身不支持对象引用关系的保留,也没有对应的标准JSON结构可以表达引用指向。你当前的编码逻辑会把 head 指向的完整链表、tail 指向的尾节点分别编码为两份完全独立的节点数据,解码后得到的 tail 和 head 链表没有任何内存关联,自然无法通过 tail 操作 head 链表。

最优解决方案

不需要在编码阶段处理引用,直接去掉 tail 的序列化逻辑,解码时通过 head 链表重新计算得到尾节点即可,改动最小且稳定可靠:

public class Queue: Sequence, Codable {
    fileprivate var head: Node?
    private var tail: Node?
    private var length: Int
    
    init() {
        head = nil
        tail = nil
        length = 0
    }

    enum CodingKeys: CodingKey {
        // 只需要序列化head和length,tail可以推导出来
        case head, length
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(head, forKey: .head)
        try container.encode(length, forKey: .length)
    }

    public required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        head = try container.decode(Node?.self, forKey: .head)
        length = try container.decode(Int.self, forKey: .length)
        // 遍历head链表找到尾节点赋值给tail
        var current = head
        while current?.next != nil {
            current = current?.next
        }
        tail = current
    }
}

其他可选方案

如果你确实需要保留对象引用的序列化能力,可以改用 NSKeyedArchiver 替代 JSONEncoder,它支持Objective-C运行时的引用关系保留,但是需要让你的 Node 和 Queue 继承自 NSObject 并实现 NSCoding 协议,实现成本更高,且序列化后的结果是二进制格式,可读性远低于JSON,非特殊需求不推荐使用。

内容的提问来源于stack exchange,提问作者yo1nk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 02:36:04