(KVO)是否有可能在不知道谁在观察的情况下移除物体的所有观察者?

时间:2015-07-07 20:38:34

标签: objective-c cocoa key-value-observing

这是我当前的情景: 有一个对象,我会复制它,这样我就可以修改属性而无需触摸原始对象。当我完成副本后,它会被解除谴责,但我收到了这些警告:

ImageDocument *selfCopy = [self copy];

这就是我复制对象的方式:

LineGraphic

我相信当我这样做时,LineGraphic属性的所有观察者都会在self的副本中观察selfCopy的副本。然后当NSNotifications被解除谴责时,会出现这些警告。

我认为最好的解决方案就是删除观察者 - 因为在副本的情况下,他们不需要在那里。

从在线搜索,我只能找到删除对象正在进行的所有观察的方法。但我需要另一种方法,从对象中删除所有观察者。此外,很多资源总是引用删除LineGraphic的观察者,而我需要删除关键路径的观察者(KVO)

我在想,如果所有其他方法都失败了,我可以迭代观察对象的所有观察者(<%= simple_form_for(@post, :html => { :multipart => true }) do |f| %> <% if @post.errors.any? %> <div id="error_explanation"> <h2, class: "white"><%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:</h2> <ul> <% @post.errors.full_messages.each do |message| %> <li, class: "white"><%= message %></li> <% end %> </ul> </div> <% end %> <%= f.input :title %> <%= f.input :subtitle %> <%= f.input :author %> <%= f.input :content, as: :text %> <%= f.input :publish, as: :select %> <%= f.association :tags, as: :check_boxes %> <div id="tabs"> <ul> <li><a href="#tabs-1">Upload Images</a></li> <li><a href="#tabs-2">Link to Video</a></li> <li><a href="#tabs-3">Quote</a></li> </ul> <div id="tabs-1"> <%= f.simple_fields_for :post_attachments do |p| %> <div class="field"> <%= p.input :media, as: :file, :multiple => true, name: "post_attachments[media][]" %> </div> <% end %> <div class="actions"></br> <%= f.button :submit %> </div> </div> <div id="tabs-2"> <div class="field"> <%= f.label :video_link %><br> <%= f.text_field :video_link %> </div> <div class="actions"></br> <%= f.button :submit %> </div> </div> <div id="tabs-3"> <div class="field"> <%= f.label :quote_text %><br> <%= f.text_field :quote_text %> </div> <div class="field"> <%= f.label :quote_author %><br> <%= f.text_field :quote_author %> </div> <div class="field"> <%= f.label :quote_source %><br> <%= f.text_field :quote_source %> </div> <div class="actions"></br> <%= f.button :submit %> </div> </div> </div> <script> $(function() { $("#tabs").tabs(); }); </script> <% end %> ) - 但问题是:有很多观察者,有两个:如果稍后会添加更多观察者,他们必须在此代码中添加删除它们。所以这个解决方案真的不会很好用

1 个答案:

答案 0 :(得分:3)

  

是否可以在不知道谁在观察的情况下删除对象的所有观察者?

是的,但是 ......

你的问题是KVO模型是围绕观察者负责注册和注销观察者的想法而设计的;它不是观察对象的责任;而你正试图篡夺那种模式。

如果被删除的对象不是观察者,removeObserver方法将抛出异常;如果你自己删除一个观察者,那么观察者就不会知道,在某些时候会尝试取消注册,你会得到一个例外,不好。

因此,请仔细考虑这是否是您真正想做的事情。

还想做吗?

  

我相信当我这样做时,LineGraphic属性的所有观察者都会在LineGraphic的副本中观察到self的副本。

这不是预期的通常行为,KVO用于观察特定实例并复制该实例创建新的不同对象。可以实现复制,以便复制观察者,但这一般会引起混淆,不推荐 - 观察者不会意识到他们现在正在观察不同的对象,因此以后无法取消注册... < / p>

还想做吗?

嗯,已被警告 ...认为压倒一切,详情留给你。

另一种建议:

不要篡夺KVO,使用它。

向您的类添加一个方法,该方法从另一个实例(您的替换对象)更新实例(您的原始对象)。此方法可以直接更新属性的后备变量,不用调用setter,并从KVO的willChange&amp; didChange组,以便在整个对象更新之前不会发出通知。

现在您可以创建&#34;替换&#34;,然后更新原始文件。你的观察者将继续观察同一个物体,并在时间到来时自行取消注册。

HTH