【问题标题】:How can I call `didSet` method using `Codable` protocol如何使用 `Codable` 协议调用`didSet` 方法
【发布时间】:2017-12-21 01:58:45
【问题描述】:

如何使用Codable 协议调用didSet 方法。

    class Sample: Codable{
        var text : String? {
            didSet {
                print("didSet") // do not call
                extended_text = "***" + text! + "***"
            }
        }
        var extended_text : String?
    }

    let sample_json = "{\"text\":\"sample text\"}"
    let decoder = JSONDecoder()
    let sample = try! decoder.decode(Sample.self, from: sample_json.data(using: .utf8)!)
    print(sample.text!)
    print(sample.extended_text ?? "") 

【问题讨论】:

    标签: swift swift4 codable


    【解决方案1】:

    您应该将extendedText 设为只读计算属性,而不是使用 didSet。请注意,在命名属性时使用 camelCase 而不是 snake_case 是 Swift 约定:

    struct Sample: Codable {
        let text: String
        var extendedText: String {
            return "***" + text + "***"
        }
    }
    

    let sampleJson = """
    {"text":"sample text"}
    """
    
    do {
        let sample = try JSONDecoder().decode(Sample.self, from: Data(sampleJson.utf8))
        print(sample.text)            // "sample text\n"
        print(sample.extendedText)    // "***sample text***\n"
    } catch {
        print(error)
    }
    

    如果您的目标是在初始化 Codable 结构时运行一个方法,另一种方法是编写您自己的自定义解码器:

    class Sample: Codable {
        let text: String
        required init(from decoder: Decoder) throws {
            let container = try decoder.singleValueContainer()
            text = try container.decode(String.self)
            print("did set")
        }
    }
    

    let sampleJson = "{\"text\":\"sample text\"}"
    let decoder = JSONDecoder()
    do {
        let sample = try decoder.decode([String: Sample].self, from: Data(sampleJson.utf8))
        print(sample["text"]?.text ?? "")
    } catch {
        print(error)
    }
    

    这将打印:

    设置好了

    示例文本

    【讨论】:

    • 谢谢。你是对的。但是,我的代码是示例。实际上处理更复杂,我想我需要保留转换后的对象。很抱歉我说得不够清楚。
    • 谢谢。我修正了误导性的表述。
    • @MaikoOhkawa 请注意,这与Codable 协议无关。如果您设置文本属性sample.text = "any text",它将调用didSet,但不会在初始化classstruct时调用
    • 我不知道“但在初始化你的类或结构时不知道”。我懂了。我的问题澄清了。我会考虑另一种处理。非常感谢。
    • @MaikoOhkawa 你可以做的是创建一个自定义解码器初始化器并在那里执行你需要的任何东西。
    猜你喜欢
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多