首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何制作JSONDecoder实例的副本?

如何制作JSONDecoder实例的副本?
EN

Stack Overflow用户
提问于 2021-02-25 14:25:52
回答 2查看 84关注 0票数 0

我希望从默认实例复制不同的JSONDecoder实例。JSONDecoder似乎是一个class,但是它没有.copy() API。

代码语言:javascript
复制
extension JSONDecoder {
    static let `default` = JSONDecoder()
}

let decoder2: JSONDecoder = .default
decoder2.keyDecodingStrategy = .convertFromSnakeCase

print(JSONDecoder.default.keyDecodingStrategy) // convertFromSnakeCase

在本例中,decoder2突变适用于JSONDecoder.default。在变异之前,我如何复制到decoder2呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-02-25 16:32:49

没有副本的原因是JSONDecoder不符合NSCopying。如果您关注线程安全,并且能够在没有引用的情况下传递对象,则需要包装器结构而不是类,并且不公开声明为私有的解码器。这样,您就可以初始化自定义对象,但无法更改解码器属性:

代码语言:javascript
复制
struct JSONDecoderWrapper {
    private let decoder = JSONDecoder()
}

代码语言:javascript
复制
extension JSONDecoderWrapper {
    init(dataDecodingStrategy: JSONDecoder.DataDecodingStrategy = .base64,
         dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate,
         keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys,
         nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy = .throw,
         userInfo: [CodingUserInfoKey : Any] = [:]) {
        decoder.dataDecodingStrategy = dataDecodingStrategy
        decoder.dateDecodingStrategy = dateDecodingStrategy
        decoder.keyDecodingStrategy = keyDecodingStrategy
        decoder.nonConformingFloatDecodingStrategy = nonConformingFloatDecodingStrategy
        decoder.userInfo = userInfo
    }
}

代码语言:javascript
复制
extension JSONDecoderWrapper {
    /// Summary:
    /// Decodes a top-level value of the given type from the given JSON representation.
    func decode<T>(_ type: T.Type, from data: Data) throws -> T where T : Decodable {
        try decoder.decode(type, from: data)
    }
}

代码语言:javascript
复制
extension JSONDecoderWrapper {
    var dataDecodingStrategy: JSONDecoder.DataDecodingStrategy { decoder.dataDecodingStrategy }
    var dateDecodingStrategy: JSONDecoder.DateDecodingStrategy { decoder.dateDecodingStrategy }
    var keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy { decoder.keyDecodingStrategy }
    var nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy { decoder.nonConformingFloatDecodingStrategy }
    var userInfo: [CodingUserInfoKey : Any] { decoder.userInfo }
}

代码语言:javascript
复制
extension JSONDecoderWrapper {
    func copy(dataDecodingStrategy: JSONDecoder.DataDecodingStrategy? = nil,
              dateDecodingStrategy: JSONDecoder.DateDecodingStrategy? = nil,
              keyDecodingStrategy: JSONDecoder.KeyDecodingStrategy? = nil,
              nonConformingFloatDecodingStrategy: JSONDecoder.NonConformingFloatDecodingStrategy? = nil,
              userInfo: [CodingUserInfoKey : Any]? = nil) -> Self {
       .init(dataDecodingStrategy: dataDecodingStrategy ?? decoder.dataDecodingStrategy, dateDecodingStrategy: dateDecodingStrategy ?? decoder.dateDecodingStrategy, keyDecodingStrategy: keyDecodingStrategy ?? decoder.keyDecodingStrategy, nonConformingFloatDecodingStrategy:  nonConformingFloatDecodingStrategy ?? decoder.nonConformingFloatDecodingStrategy, userInfo: userInfo ?? decoder.userInfo)
    }
}

操场测试

代码语言:javascript
复制
extension JSONDecoderWrapper {
    static let `default` = JSONDecoderWrapper()
}

JSONDecoderWrapper.default

// let decoder2 = JSONDecoderWrapper.default
// decoder2.keyDecodingStrategy = .convertFromSnakeCase // error Cannot assign to property: 'keyDecodingStrategy' is a get-only property
// decoder2.decoder.keyDecodingStrategy = .convertFromSnakeCase // error 'decoder' is inaccessible due to 'private' protection level

// you can make a copy changing one or mpore specific properties
let decoder2 = JSONDecoderWrapper.default.copy(keyDecodingStrategy: .convertFromSnakeCase)

print(decoder2.dataDecodingStrategy) // "base64\n"
print(decoder2.dateDecodingStrategy) // deferredToDate\n"
print(decoder2.keyDecodingStrategy) // "convertFromSnakeCase\n"
print(decoder2.nonConformingFloatDecodingStrategy) // "throw\n"
print(decoder2.userInfo) // "[:]\n"
票数 2
EN

Stack Overflow用户

发布于 2021-02-25 14:52:40

您可以随意编写自己的复制方法,没有那么多属性可复制。或者,如果您希望从同一模板开始,则可以使用工厂方法来创建具有默认配置的解码器。

代码语言:javascript
复制
extension JSONDecoder {
    //copy
    func copy() -> JSONDecoder {
        let decoder = JSONDecoder()
        decoder.dataDecodingStrategy = self.dataDecodingStrategy
        decoder.dateDecodingStrategy = self.dateDecodingStrategy
        //...
        return decoder
    }

    //factory
    static func createDefault() -> JSONDecoder {
        let decoder = JSONDecoder()
        decoder.dataDecodingStrategy = .base64
        decoder.dateDecodingStrategy = .iso8601
        //...

        return decoder
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66370412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档