对象标识符的编码
Experiencing an issue with property values changing after encoding and decoding a Codable object? You may have run into the same problem I had with setting identifiers using UUID().uuidString
as the initial value.
在编码和解码可编码对象后遇到属性值更改的问题? 您可能遇到了与使用UUID().uuidString
作为初始值来设置标识符的问题。
问题 (The Problem)
Say you have a Codable
object that generates its own identifier like so:
假设您有一个Codable
对象,它会生成自己的标识符,如下所示:
Generating the UUID inline will create a new unique identifier every time a new Employee
object is instantiated. Perfect! However, the value present when you encode won’t be the same value you get back when you decode.
每次实例化新的Employee
对象时,生成内联UUID都会创建一个新的唯一标识符。 完善! 但是,编码时出现的值将与解码时返回的值不同。
原因 (The Cause)
Because the identifier
property is declared as a let
with a default value, the non-mutable property cannot be assigned a new value. Codable
is ultimately initializing your object using a Decoder
. You can recreate this problem by creating your own initialize from decoder method, like so:
由于将identifier
属性声明为具有默认值的let
,因此无法为non-mutable属性分配新值。 Codable
最终使用Decoder
初始化您的对象。 您可以通过从解码器方法创建自己的Initialize来重新创建此问题,如下所示:
Notice how the above example does not compile with the following error: “Immutable value ‘self.identifier’ may only be initialized once”. Because the non-mutable identifier
property already has a value assigned, UUID().uuidString
, it cannot be assigned the value from the decoded container.
请注意,上面的示例如何不与以下错误一起编译:“ 不可变值'self.identifier'只能初始化一次”。 由于非可变identifier
属性已经为UUID().uuidString
分配了值,因此无法从解码后的容器中为其分配值。
解决方案 (Solutions)
Make the property mutable: The most simple and straight forward workaround is to declare the identifier
property as a mutable var
. This will allow the initializer to override the default value with the value in the decoded container.
使属性可变:最简单直接的解决方法是将identifier
属性声明为可变var
。 这将允许初始化程序使用解码容器中的值覆盖默认值。
In Xcode 12, a new compile time warning is issued when using a non-mutable property and initial value on an object that implements the Decodable
protocol: “Immutable property will not be decoded because it is declared with an initial value which cannot be overwritten. Make the property mutable instead”
在Xcode 12中,当在实现了Decodable
协议的对象上使用非可变属性和初始值时,会发出新的编译时警告: “ Immutable属性不会被解码,因为它声明的初始值无法覆盖。 而是使属性可变”
Set the initial value in a constructor:If you do not want to make the property mutable, another option is to set the initial value for the identifier
property within a constructor. Like so:
在构造函数中设置初始值:如果您不想使属性可变,另一种选择是在构造函数中设置identifier
属性的初始值。 像这样:
Because the non-mutable identifier
property no longer has an initial value by default, the initializer used by Codable
can successfully set the value to the value in the decoded container.
由于默认情况下非可变identifier
属性不再具有初始值,因此Codable
使用的初始化Codable
可以成功地将值设置为已解码容器中的值。
This is the solution our team ended up using. We felt that it was better to keep the identifier property non-mutable and set the value within a custom initializer that already existed.
这是我们团队最终使用的解决方案。 我们认为最好将标识符属性保持不可更改,并在已存在的自定义初始化程序中设置该值。
Mason is an iOS developer social distancing with his dog at Livefront
Mason是iOS开发人员与他的狗在 Livefront进行 社交 疏离
翻译自: https://medium.com/livefront/fixing-issues-with-codable-identifiers-b74f1480cf58
对象标识符的编码