我希望从默认实例复制不同的JSONDecoder实例。JSONDecoder似乎是一个class,但是它没有.copy() API。
extension JSONDecoder {
static let `default` = JSONDecoder()
}
let decoder2: JSONDecoder = .default
decoder2.keyDecodingStrategy = .convertFromSnakeCase
print(JSONDecoder.default.keyDecodingStrategy) // convertFromSnakeCase在本例中,decoder2突变适用于JSONDecoder.default。在变异之前,我如何复制到decoder2呢?
发布于 2021-02-25 16:32:49
没有副本的原因是JSONDecoder不符合NSCopying。如果您关注线程安全,并且能够在没有引用的情况下传递对象,则需要包装器结构而不是类,并且不公开声明为私有的解码器。这样,您就可以初始化自定义对象,但无法更改解码器属性:
struct JSONDecoderWrapper {
private let decoder = JSONDecoder()
}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
}
}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)
}
}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 }
}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)
}
}操场测试
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"发布于 2021-02-25 14:52:40
您可以随意编写自己的复制方法,没有那么多属性可复制。或者,如果您希望从同一模板开始,则可以使用工厂方法来创建具有默认配置的解码器。
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
}
}https://stackoverflow.com/questions/66370412
复制相似问题