如果 KVO 观察到的值在短时间内发生两次变化,那么 observeValueForKeyPath() 会发生什么?
If a value being observed by KVO changes twice in a short amount of time, what will happen in observeValueForKeyPath()?
根据我的理解,由于我没有为我的 KVO 使用单独的线程(Swift 中的 observeValueForKeyPath),当我观察到的值发生变化时,将使用同一线程调用 observeValueForKeyPath()。我不确定的是说我在 observeValueForKeyPath() 中间,然后值再次改变,会发生什么?我现在的执行会不会被打断,又从observeValueForKeyPath()的开头重新开始?在这种情况下,一旦后一个 observeValueForKeyPath() 完成,我是否会恢复到被打断的前一个 observeValueForKeyPath()?在这种情况下,如果我在 observeValueForKeyPath() 中操作数据,我想它会导致竞争条件。
谢谢。
KVO 真的很酷。实际发生的事情(由 mike ash 发现)是运行时将子类化您的 observed 对象,并覆盖 setter 对于正在观察的 属性。被覆盖的 setter 有额外的指令,最终会为 observing 对象显式调用 -observeValueForKey
。
那么,如果您在 -observeValueForKey
内更改指定键路径处的值,会发生什么情况,您最终会得到 -observeValueForKey
消息发送到 observed(相同)对象。所以正如你所说,你当前的执行将被中断,一些与 KVO 相关的堆栈帧将被放置在你的调用堆栈中,如果一切都正确解决,你将像往常一样继续。
当然,令人厌烦的是,如果在 -observeValueForKey
内对于某个对象,您 总是 启动对同一对象的通知。您将陷入无限循环,您的应用程序将崩溃。
而且我不会将您所描述的称为竞争条件,因为在任何时候都不会有两个对象同时尝试 read/write 一个对象。你只需要厌倦阅读和写作的顺序,因为这可能不是你所期望的
根据我的理解,由于我没有为我的 KVO 使用单独的线程(Swift 中的 observeValueForKeyPath),当我观察到的值发生变化时,将使用同一线程调用 observeValueForKeyPath()。我不确定的是说我在 observeValueForKeyPath() 中间,然后值再次改变,会发生什么?我现在的执行会不会被打断,又从observeValueForKeyPath()的开头重新开始?在这种情况下,一旦后一个 observeValueForKeyPath() 完成,我是否会恢复到被打断的前一个 observeValueForKeyPath()?在这种情况下,如果我在 observeValueForKeyPath() 中操作数据,我想它会导致竞争条件。 谢谢。
KVO 真的很酷。实际发生的事情(由 mike ash 发现)是运行时将子类化您的 observed 对象,并覆盖 setter 对于正在观察的 属性。被覆盖的 setter 有额外的指令,最终会为 observing 对象显式调用 -observeValueForKey
。
那么,如果您在 -observeValueForKey
内更改指定键路径处的值,会发生什么情况,您最终会得到 -observeValueForKey
消息发送到 observed(相同)对象。所以正如你所说,你当前的执行将被中断,一些与 KVO 相关的堆栈帧将被放置在你的调用堆栈中,如果一切都正确解决,你将像往常一样继续。
当然,令人厌烦的是,如果在 -observeValueForKey
内对于某个对象,您 总是 启动对同一对象的通知。您将陷入无限循环,您的应用程序将崩溃。
而且我不会将您所描述的称为竞争条件,因为在任何时候都不会有两个对象同时尝试 read/write 一个对象。你只需要厌倦阅读和写作的顺序,因为这可能不是你所期望的