我正在Struct
模型对象上实现观察者设计模式。我的想法是,我将沿着UIViewController
链传递我的模型,并且随着每个控制器的修改,先前的控制器也将随着对象的更改而更新。
[我知道可以通过使用class
而不是struct
并直接通过引用修改对象来解决此问题,但是我试图学习有关使用structs
的更多信息。
struct ModelObject {
var data: Int = 0 {
didSet {
self.notify()
}
}
private var observers = [ModelObserver]()
mutating func attachObserver(_ observer: ModelObserver){
self.observers.append(observer)
}
private func notify(){
for observer in observers {
observer.modelUpdated(self)
}
}
}
protocol ModelObserver {
var observerID: Int { get }
func modelUpdated(_ model: ModelObject)
}
class MyViewController : UIViewController, ModelObserver {
var observerID: Int = 1
var model = ModelObject()
override func viewDidLoad() {
self.model.attachObserver(self)
self.model.data = 777
}
func modelUpdated(_ model: ModelObject) {
print("received updated model")
self.model = model //<-- problem code
}
}
简单地说,当data
发生更改时,我的模型对象通过调用notify()
通知任何观察者。
[我现在的问题是内存访问:data
设置为777
时,self.model
被独占访问,并且当它调用notify
时又调用了modelUpdated
并最终调用self.model = model
时,我们得到了一个错误:
Simultaneous accesses to 0x7fd8ee401168, but modification requires exclusive access.
我该如何解决此内存访问问题?
[如果您观察到“事物”,则该“事物”具有身份。您正在观察这件事。您无法观察到数字4。它没有身份。每4个与其他4个相同。结构是值。他们没有身份。您不应像观察Int那样尝试观察它们(Int实际上是Swift中的结构)。
每次将结构传递给函数时,都会复制该结构。因此,当您说self.model = model
时,是在说“制作模型的[[copy,并将其分配给此属性”。但是您仍然处于排他性访问块中,因为每次修改结构时,它也会复制一个副本。