(KVO) 是否可以在不知道谁在观察的情况下移除对象的所有观察者?
(KVO) Is it possible to remove all observers of an object, without knowing who is observing?
这是我目前的情况:
有一个对象,我复制了它,这样我就可以修改属性 w/o 来接触原始对象。当我完成副本时,它会被解除分配,但我收到以下警告:
An instance 0x6080001250a0 of class LineGraphic was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x618000043ea0> (
<NSKeyValueObservance 0x6180000c1ce0: Observer: 0x6000001834d0, Key path: points, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000056fe0>
<NSKeyValueObservance 0x6180000c1e30: Observer: 0x6000001834d0, Key path: shadow, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000057460>
<NSKeyValueObservance 0x6180000c9bc0: Observer: 0x6000001834d0, Key path: secondHeadStyle, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x60000005d7c0>
<NSKeyValueObservance 0x6180000c1ff0: Observer: 0x6000001834d0, Key path: lineStyle, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000051640>
<NSKeyValueObservance 0x6180000c1f10: Observer: 0x6000001834d0, Key path: fillColor, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000054f70>
<NSKeyValueObservance 0x6180000c1b20: Observer: 0x6000001834d0, Key path: strokeWidth, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000054d30>
<NSKeyValueObservance 0x6180000c2140: Observer: 0x6000001834d0, Key path: strokeColor, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x6000000548b0>
<NSKeyValueObservance 0x6180000c1d50: Observer: 0x6000001834d0, Key path: firstHeadStyle, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000055060>
<NSKeyValueObservance 0x6180000c1ea0: Observer: 0x6000001834d0, Key path: opacity, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x6080002421f0>
<NSKeyValueObservance 0x6180000c1f80: Observer: 0x6000001834d0, Key path: visibleOpacity, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x608000247560>
<NSKeyValueObservance 0x6180000ca090: Observer: 0x6000001834d0, Key path: rotation, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x60800024a590>
)
这是我复制对象的方式:
ImageDocument *selfCopy = [self copy];
我相信当我这样做时,LineGraphic
属性 的所有观察者也会在 self
的副本中观察 LineGraphic
的副本。然后当 selfCopy
被解除分配时,就会出现这些警告。
我想最好的解决办法就是移除观察者——因为在副本的情况下,他们根本不需要在那里。
通过在线搜索,我只能找到删除对象正在进行的所有观察的方法。但我需要它的另一种方式,从一个对象中删除所有观察者。此外,很多资源总是引用移除 NSNotifications
的观察者,而我需要移除关键路径 (KVO)
的观察者
我在想如果一切都失败了,我可以遍历被观察对象的所有观察者(LineGraphic
)——但问题是一个:有很多观察者,两个:如果以后添加了更多观察者,他们将不得不在此代码中添加删除它们。所以这个方案真的行不通
Is it possible to remove all observers of an object, without knowing who is observing?
是的,但是...
你的问题是KVO模型是围绕观察者负责作为观察者注册和注销的想法设计的;不是被观察对象的责任;而你正试图篡夺该模型。
如果被移除的对象不是观察者,removeObserver
方法将抛出异常;如果您自己删除一个观察者,那么观察者将不知道,会在某个时候尝试取消注册,并且您会得到一个异常,不好。
所以仔细想想这是否是你真正想做的。
还想做吗?
I believe that when I am doing this, all of the observers for the LineGraphic
property also observe the copy of LineGraphic
in the copy of self
.
这不是预期的常见行为,KVO 用于监视 特定实例 并复制该实例会创建一个新的不同对象。可以实现复制以便复制观察者,但这通常会造成混淆并且不推荐 - 观察者不会意识到他们现在正在观察不同的对象,因此以后不能注销自己......
还想做吗?
嗯你已被警告...认为凌驾于一切之上,细节留给你。
替代建议:
不要篡夺KVO,用它来工作。
向您的 class 添加一个方法,该方法从另一个实例(您的替换对象)更新一个实例(您的原始对象)。此方法可以直接更新属性的支持变量,无需 调用设置器,并从 KVO 的 willChange
和 didChange
组调用方法,这样就不会发出通知直到整个对象被更新。
现在您可以创建自己的 "replacement",然后更新原始文件。您的观察者将继续观察同一个对象,并在时机成熟时自行注销。
HTH
这是我目前的情况: 有一个对象,我复制了它,这样我就可以修改属性 w/o 来接触原始对象。当我完成副本时,它会被解除分配,但我收到以下警告:
An instance 0x6080001250a0 of class LineGraphic was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x618000043ea0> (
<NSKeyValueObservance 0x6180000c1ce0: Observer: 0x6000001834d0, Key path: points, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000056fe0>
<NSKeyValueObservance 0x6180000c1e30: Observer: 0x6000001834d0, Key path: shadow, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000057460>
<NSKeyValueObservance 0x6180000c9bc0: Observer: 0x6000001834d0, Key path: secondHeadStyle, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x60000005d7c0>
<NSKeyValueObservance 0x6180000c1ff0: Observer: 0x6000001834d0, Key path: lineStyle, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000051640>
<NSKeyValueObservance 0x6180000c1f10: Observer: 0x6000001834d0, Key path: fillColor, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000054f70>
<NSKeyValueObservance 0x6180000c1b20: Observer: 0x6000001834d0, Key path: strokeWidth, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000054d30>
<NSKeyValueObservance 0x6180000c2140: Observer: 0x6000001834d0, Key path: strokeColor, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x6000000548b0>
<NSKeyValueObservance 0x6180000c1d50: Observer: 0x6000001834d0, Key path: firstHeadStyle, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x600000055060>
<NSKeyValueObservance 0x6180000c1ea0: Observer: 0x6000001834d0, Key path: opacity, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x6080002421f0>
<NSKeyValueObservance 0x6180000c1f80: Observer: 0x6000001834d0, Key path: visibleOpacity, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x608000247560>
<NSKeyValueObservance 0x6180000ca090: Observer: 0x6000001834d0, Key path: rotation, Options: <New: NO, Old: YES, Prior: YES> Context: 0x0, Property: 0x60800024a590>
)
这是我复制对象的方式:
ImageDocument *selfCopy = [self copy];
我相信当我这样做时,LineGraphic
属性 的所有观察者也会在 self
的副本中观察 LineGraphic
的副本。然后当 selfCopy
被解除分配时,就会出现这些警告。
我想最好的解决办法就是移除观察者——因为在副本的情况下,他们根本不需要在那里。
通过在线搜索,我只能找到删除对象正在进行的所有观察的方法。但我需要它的另一种方式,从一个对象中删除所有观察者。此外,很多资源总是引用移除 NSNotifications
的观察者,而我需要移除关键路径 (KVO)
我在想如果一切都失败了,我可以遍历被观察对象的所有观察者(LineGraphic
)——但问题是一个:有很多观察者,两个:如果以后添加了更多观察者,他们将不得不在此代码中添加删除它们。所以这个方案真的行不通
Is it possible to remove all observers of an object, without knowing who is observing?
是的,但是...
你的问题是KVO模型是围绕观察者负责作为观察者注册和注销的想法设计的;不是被观察对象的责任;而你正试图篡夺该模型。
如果被移除的对象不是观察者,removeObserver
方法将抛出异常;如果您自己删除一个观察者,那么观察者将不知道,会在某个时候尝试取消注册,并且您会得到一个异常,不好。
所以仔细想想这是否是你真正想做的。
还想做吗?
I believe that when I am doing this, all of the observers for the
LineGraphic
property also observe the copy ofLineGraphic
in the copy ofself
.
这不是预期的常见行为,KVO 用于监视 特定实例 并复制该实例会创建一个新的不同对象。可以实现复制以便复制观察者,但这通常会造成混淆并且不推荐 - 观察者不会意识到他们现在正在观察不同的对象,因此以后不能注销自己......
还想做吗?
嗯你已被警告...认为凌驾于一切之上,细节留给你。
替代建议:
不要篡夺KVO,用它来工作。
向您的 class 添加一个方法,该方法从另一个实例(您的替换对象)更新一个实例(您的原始对象)。此方法可以直接更新属性的支持变量,无需 调用设置器,并从 KVO 的 willChange
和 didChange
组调用方法,这样就不会发出通知直到整个对象被更新。
现在您可以创建自己的 "replacement",然后更新原始文件。您的观察者将继续观察同一个对象,并在时机成熟时自行注销。
HTH