我有一些对象,它们是我通过协议扩展提供的函数structs从 JSON 字典 ( [String : Any])初始化的(请参阅使用字典/数组初始化符合 Codable 的对象)。initDecodable
所以基本上,我有看起来像这样的对象:
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更改时设置它。
我可以使用didSeton 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)。
我能想到的唯一其他选择是创建我刚刚提到的那个变异函数,并在两个didSetwhenarrayOfObjectModelAVal更改中调用它,然后使用以下内容更新我的对象初始化调用:
guard let objectDictArray = responseObject as? [[String : Any]] else { return }
let objects = objectDictArray
.compactMap({ try? ObjectModelB(any: $0) })
.forEach({ $0.updateProperties() })
但是现在updateProperties任何人都可以随时调用它(这很糟糕,因为它真的很费力),并且不能保证在创建对象数组时它甚至会被调用,因为开发人员可能会忘记做这forEach部分。因此,为什么我想要一种updateProperties在对象初始化后立即自动调用函数的方法。