Ios 如何检测结构中的更改,包括其任何属性或其属性等。?
假设我有以下设置:Ios 如何检测结构中的更改,包括其任何属性或其属性等。?,ios,swift,Ios,Swift,假设我有以下设置: struct Sandwich { var bread: Bread var fillings: [Filling] var slices: Int } enum Bread: String { case white case wholemeal } struct Filling { let name: String let calories: Int } 因此,我们有一个父结构,其中包含一些其他属性、枚举、其他结
struct Sandwich {
var bread: Bread
var fillings: [Filling]
var slices: Int
}
enum Bread: String {
case white
case wholemeal
}
struct Filling {
let name: String
let calories: Int
}
因此,我们有一个父结构,其中包含一些其他属性、枚举、其他结构等,作为子结构。他们可能也有自己的孩子
我试图做的是检测我的三明治的任何更改,发布通知或使用Combine发布更改,等等
这是我的三明治:
var三明治=三明治(面包:白色,馅料:[馅料(名称:“鸡肉”,卡路里:100)],切片:2)
现在,假设我几分钟后来,决定再添加一种填充物:
sandwich.fillings.append(馅料(名称:“莴苣”,卡路里:10)]
或者,也许他们决定增加订单:
sandwich.slices+=2
我想做的是保持循环。我想要一个通知,让我知道我的Sandwich
是否以任何方式发生了变化,是它的一个子属性发生了变化,还是它的一个孙子的属性发生了变化,甚至是在树的更深处
我还想使用我的Sandwich
的这些更改版本来构建一个撤销/重做队列,因此每次更改时的状态最好是可记录/可存储的
我意识到我可以编写大量的委托和其他东西来完成这项工作,但我希望在模型发生变化时(即,如果我添加了一个新的属性等),能够自动工作并继续工作。KVO
和Combine
都适用于从NSObject
继承的类
自动更改需要运行时
使用class
,而不是struct
模型部件:
使用KVO:
使用联合收割机:
class ViewController: UIViewController {
@objc var food = Sandwich()
var cancellableFilling: Cancellable?
var cancellableSlice: Cancellable?
override func viewDidLoad() {
super.viewDidLoad()
// use Combine
cancellableFilling = food.publisher(for: \.fillings)
.sink(){
val in
print("food.fillings now \(val).")
}
cancellableSlice = food.publisher(for: \.slices)
.sink(){
val in
print("food.slices now \(val).")
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
food.fillings.append(Filling())
food.slices += 1
}
}
最好的办法是在所有变量上都有一个didSet,无论何时调用didSet,您都要记录状态或使用ObservieObject执行您需要的操作?
class ViewController: UIViewController {
@objc var food = Sandwich()
var observationFilling: NSKeyValueObservation?
var observationSlice: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
// use KVO
observationFilling = observe(\.food.fillings, options: [.new]) { object, change in
if let val = change.newValue{
print ("food.fillings now \(val).")
}
}
observationSlice = observe(\.food.slices, options: [.new]) { object, change in
if let val = change.newValue{
print ("food.slices now \(val).")
}
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
food.fillings.append(Filling())
food.slices += 1
}
}
class ViewController: UIViewController {
@objc var food = Sandwich()
var cancellableFilling: Cancellable?
var cancellableSlice: Cancellable?
override func viewDidLoad() {
super.viewDidLoad()
// use Combine
cancellableFilling = food.publisher(for: \.fillings)
.sink(){
val in
print("food.fillings now \(val).")
}
cancellableSlice = food.publisher(for: \.slices)
.sink(){
val in
print("food.slices now \(val).")
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
food.fillings.append(Filling())
food.slices += 1
}
}