我有一些对象,它们是我通过协议扩展提供的函数structs
从 JSON 字典 ( [String : Any]
)初始化的(请参阅使用字典/数组初始化符合 Codable 的对象)。init
Decodable
所以基本上,我有看起来像这样的对象:
struct ObjectModelA: Codable {
var stringVal: String
var intVal: Int
var boolVal: Bool
// Coding keys omitted for brevity
}
struct ObjectModelB: Codable {
var doubleVal: Double
var arrayOfObjectModelAVal: [ObjectModelA]
// Coding keys omitted for brevity
var complicatedComputedVar: String {
// expensive operations using the values in arrayOfObjectModelAVal
}
}
ObjectModelB
包含一个数组ObjectModelA
,并且它还有一个属性,我只想在arrayOfObjectModelAVal
更改时设置它。
我可以使用didSet
on arrayOfObjectModelAVal
,但这只会捕获未来对arrayOfObjectModelAVal
属性的更改。问题是我正在使用 Web 服务来检索 JSON 数据以创建 ObjectModelB ( ) 数组[[String : Any]]
,并且我像这样构建它:
guard let objectDictArray = responseObject as? [[String : Any]] else { return }
let objects = objectDictArray.compactMap({ try? ObjectModelB(any: $0) })
我的对象是在compactMap
闭包内创建的,并且init
不会触发didSet
.
我也不能“覆盖”协议提供的 init init
(Decodable
闭包中的那个:),try? ObjectModelB(any: $0)
因为我的对象是 astruct
并且这不是继承,它只是协议提供的初始化程序。否则,我会“覆盖”init
我的对象中的 ,然后只是执行super.init
某种变异函数来更新我的复杂属性,然后我会创建我的复杂属性private(set)
。
我能想到的唯一其他选择是创建我刚刚提到的那个变异函数,并在两个didSet
whenarrayOfObjectModelAVal
更改中调用它,然后使用以下内容更新我的对象初始化调用:
guard let objectDictArray = responseObject as? [[String : Any]] else { return }
let objects = objectDictArray
.compactMap({ try? ObjectModelB(any: $0) })
.forEach({ $0.updateProperties() })
但是现在updateProperties
任何人都可以随时调用它(这很糟糕,因为它真的很费力),并且不能保证在创建对象数组时它甚至会被调用,因为开发人员可能会忘记做这forEach
部分。因此,为什么我想要一种updateProperties
在对象初始化后立即自动调用函数的方法。