【问题标题】:Which is a better way to remove Notification observer哪个是删除通知观察者的更好方法
【发布时间】:2012-04-19 20:31:55
【问题描述】:

我通常使用如下示例的 NSNotification:

在 viewDidLoad 中:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(bar:) name:kName2 object:nil];

在 viewDidUnload 和 dealloc 中:

[[NSNotificationCenter defaultCenter] removeObserver:self];

但是一位朋友告诉我,我不应该使用[[NSNotificationCenter defaultCenter] removeObserver:self];,因为它会删除所有的观察者,包括超类的 .他建议我使用下面的代码来一一移除观察者。

[[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:kName2 object:nil];

我检查了 ASIHttpRequest 库的代码 (https://github.com/pokeb/asi-http-request)。它遵循我朋友的建议。

我想知道我的朋友是否正确?在我看来,由于当前实例将被卸载或释放,超类的通知也是无用的。并且有没有系统 UIViewController 子类的使用通知?

【问题讨论】:

  • 移除“超类”观察者是什么意思?观察者是一个对象实例而不是一个类。如果要释放它,它必须从所有通知中注销自己,即使它们已在超类的代码中注册。
  • @MrTJ 我的意思是在 super 的方法中添加的通知观察者。可能类实例的父亲在调用child的viewDidUnload方法时也需要观察一些通知。
  • 可能是,可能是。如果您想在 viewDidUnload 中注销,那么为了安全起见,我建议使用第二种方法(每个观察者注销)

标签: iphone ios ipad nsnotification


【解决方案1】:

随着对象消失,在dealloc 方法中使用[[NSNotificationCenter defaultCenter] removeObserver:self]; 是安全的。

ViewDidUnload 方法中,您最好将每个观察者一一移除,因为对控制器的引用仍然存在(并且您对应的viewDidLoad 应该将它们全部添加回)。

【讨论】:

    【解决方案2】:

    你的朋友是 100% 正确的。不过,是否删除 dealloc 中的所有通知观察并不重要。
    您提到了viewDidUnload,情况完全不同,因为卸载的对象会保持活动状态,您不知道何时再次添加超类的通知观察。如果将它们添加到 viewDidLoad 中,则不会有问题。如果将它们添加到 init 方法中,您只会丢失一堆重要的通知观察。

    删除具有特定名称的观察是一种很好的做法,应该从一开始就完成。

    【讨论】:

    • 谢谢。所以我们可以在dealloc 方法中使用[[NSNotificationCenter defaultCenter] removeObserver:self];,但不能在viewDidUnload 方法中使用,对吧?
    • 是的,removeObserver: 不应该在 dealloc 之外使用。但是我喜欢自己删除每个观察,所以我根本不使用removeObserver:。我对所有通知都使用特定方法removeObserver:name:object:。我喜欢让我的代码非常具体。
    【解决方案3】:

    我使用第一种方式,我从来没有想过它是否正确。如果调用了 dealloc,那么无论如何都会释放对象(超级对象)。您绝对不想要的是将 NSNotification 发送到已释放的实例。

    【讨论】:

      【解决方案4】:

      当你想删除你使用的所有通知时,

      [[NSNotificationCenter defaultCenter] removeObserver:self];
      

      如果您想删除您使用的特定通知,

      [[NSNotificationCenter defaultCenter] removeObserver:self name:kName1 object:nil];
      

      当您不再需要任何通知时,第一种方法很简单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多