内存访问与结构和观察者模式冲突
Memory access conflict with structs and observer pattern
我正在 Struct
模型对象上实施 Observer 设计模式。我的想法是,我将我的模型沿着 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.
如何解决这个内存访问问题?
如果您正在观察 "a thing,",那么 "thing" 就有一个身份。这是你正在观察的一件特别的事情。你不能观察数字 4。它是一个值;它没有身份。每 4 个都与其他 4 个相同。结构是值。他们没有身份。您不应该尝试观察它们,就像您尝试观察 Int 一样(Int 实际上是 Swift 中的一个结构)。
每次将结构传递给函数时,都会生成该结构的副本。所以当你说 self.model = model
时,你说的是 "make a copy of model, and assign it to this property." 但是你仍然处于独占访问块中,因为每次修改结构时,它也会生成一个副本。
如果你的意思是观察ModelObject,那么ModelObject应该是一个引用类型,一个class。那么你可以谈论 "this particular ModelObject" 而不是 "a ModelObject that contains these values, and is indistinguishable from any other ModelObject which contains the same values."
我正在 Struct
模型对象上实施 Observer 设计模式。我的想法是,我将我的模型沿着 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.
如何解决这个内存访问问题?
如果您正在观察 "a thing,",那么 "thing" 就有一个身份。这是你正在观察的一件特别的事情。你不能观察数字 4。它是一个值;它没有身份。每 4 个都与其他 4 个相同。结构是值。他们没有身份。您不应该尝试观察它们,就像您尝试观察 Int 一样(Int 实际上是 Swift 中的一个结构)。
每次将结构传递给函数时,都会生成该结构的副本。所以当你说 self.model = model
时,你说的是 "make a copy of model, and assign it to this property." 但是你仍然处于独占访问块中,因为每次修改结构时,它也会生成一个副本。
如果你的意思是观察ModelObject,那么ModelObject应该是一个引用类型,一个class。那么你可以谈论 "this particular ModelObject" 而不是 "a ModelObject that contains these values, and is indistinguishable from any other ModelObject which contains the same values."