当 KVO 从模型设置器触发时,防止递归地重新输入observeValueForKeypath
我有一大批模型会自我观察变化。当 setter 被触发时,模型中的观察者被调用,在该模型中,我调用 Web 服务器并更新 Web 服务器中的信息,以便它正确地拥有应有的数据。
然而,在我对网络服务器的调用中,我可以得到一个错误,从连接断开、服务器重置等到服务器说不允许更新(例如,另一个用户更改的某些其他参数阻止了更新)。
哦,断开连接的数据存储的乐趣...
有什么方法可以更新自我(即模型)而不重新触发 KVO 操作?
当我返回响应时,我可以关闭观察者,但是在执行后台服务器请求时,可能会对同一对象执行另一个用户操作。这将中断另一个调用。
请参阅此处的帖子,了解我想要做什么的解释首先获得观察结果以及完整模型的代码示例。
我打电话的部分将在观察员中如下:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqual:@"firstName"]) {
if !([serverCall value:[change objectForKey:NSKeyValueChangeNewKey]
forKey:@"firstName"]) {
// Notify the user of the problem and somehow do a
// [self setFirstName:[change objectForKey:NSKeyValueChangeOldKey]]
// without firing off a KVO which would only loop this process
}
}
if ([keyPath isEqual:@"lastName"]) {
// Do whatever I need to do
}
}
你们似乎总是提出一些好的建议,我总是感谢你们提出的任何建议。
I have a whole host of models that watch themselves for changes. When a setter is triggered, the observer in the model is called and within that model I make a call to a web server and update information in the web server so it correctly has the data it should.
However, in my call to the web server I can get back an error for anything from connection being dropped, server reset etc to the server saying the update wasn't allowed (e.g. some other parameter changed by another user prevented the update).
Oh the joys of a disconnected data store...
Is there any way that I can update self
(i.e. the model) without it re-triggering a KVO action?
I could turn off the observer when I get back the response, but another user action to the same object is possible while the background server request is being performed. This would then break the other call.
See the post here for an explanation of what I was trying to do to get the observation happening in the first place and a code example of the full model.
The portion where I am making the call would be in the observer as follows:
-(void)observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context {
if ([keyPath isEqual:@"firstName"]) {
if !([serverCall value:[change objectForKey:NSKeyValueChangeNewKey]
forKey:@"firstName"]) {
// Notify the user of the problem and somehow do a
// [self setFirstName:[change objectForKey:NSKeyValueChangeOldKey]]
// without firing off a KVO which would only loop this process
}
}
if ([keyPath isEqual:@"lastName"]) {
// Do whatever I need to do
}
}
You guys always seem to come through on some good advice and I am always grateful for any suggestions you may have.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,我最终采取了不同的策略。我没有依赖对象模型来发布更新,而是将所有内容提升一级并让控制器处理更新。
本质上,该过程如下: 根据
结果是每个控制器中的代码多一点,但是通过动态比较当前的值与新值,并且仅将已更改的值传递给服务器,我完成了相同的最终结果。
这使我能够根据更改的数量传递多个值之一,而无需一遍又一遍地调用通用服务器 API 方法来对 setter 和 getter 进行硬编码。
最终效果是,我保留了所有 KVC/KVO 通知,而不必担心绕过它或不对某些呼叫进行 KVC/KVO 更新,而不会对其他呼叫进行 KVC/KVO 更新。
Well I ended up taking a different tack. Instead of relying on the object model to post the updates, I took everything up one level and let the controller handle the updates.
Essentially the process was as follows:
It worked out being a little more code in each controller, but by dynamically comparing the current values with the new values and only passing up the ones that had changed to the server I accomplished the same net result.
This allows me to pass up one of more values based upon how many changed without having to hard-code setters and getters with a call to a common server-API method over and over again.
The net effect was that I keep all my KVC/KVO notification without worrying about bypassing it or not doing KVC/KVO updates on some calls and not on others.