使用NSNotificationCenter添加Observer / removeObserver的更好方法是什么?

时间:2012-05-17 07:09:31

标签: iphone objective-c cocoa-touch

我曾经addObserver中的viewDidLoad:removeObserver中的dealloc:。代码:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(refreshData)
                                                 name:AnyNotification
                                               object:nil];
}

- (void)dealloc
{
    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AnyNotification
                                                  object:nil];
}

但是根据一些文章说,最好addObserver viewDidAppear:removeObserver viewDidDisappear:。代码:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(refreshData)
                                                 name:AnyNotification
                                               object:nil];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];

    [[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:AnyNotification
                                                  object:nil];
}

那么,addObserver / removeObserver的更好方法是什么?

5 个答案:

答案 0 :(得分:21)

这取决于您的方案,通常最好的方法是添加viewDidLoad并删除deallocviewDidUnload(在iOS 9.0中弃用,仅使用dealloc ),但是在某些情况下,当你在不同的类中使用相同的方法(如UI效果)并且想要使用通知只调用当前屏幕的方法时,则必须在viewWillAppear中添加观察者并将其移除{{1 }或viewWillDisappear / viewDidAppear

修改 评论中的注释,谢谢@honey。

虽然现在从iOS 9开始,你不再需要关心删除观察者了。请参阅Apple release notes:“在OS X 10.11和iOS 9.0中,NSNotificationCenter和NSDistributedNotificationCenter将不再向可能已解除分配的已注册观察者发送通知。

答案 1 :(得分:4)

我通常会将其放在-viewDidAppear:-viewDidDisapear:(或-viewWillAppear:-viewWillDisappear:)中,因为在每种情况下我都遇到过我只对...感兴趣如果视图实际显示的通知。

这可能是一个过早的优化(你处理通知的代码可能需要一些时间,但如果没有显示视图可能会没用),但它也没有更多的代码 - 它&# 39;只是用不同的方法使用相同的代码......

答案 2 :(得分:1)

不要忘记NSKeyValueObservingOptionInitial。我在viewWillAppear / viewWillDisappear中使用它,所以我的UI总是最新的,即使我隐藏了那个视图控制器,也节省了资源,因为我再也不会更新它了。

答案 3 :(得分:0)

-viewWillAppear: + -viewWillDisappear:优于-viewDidAppear: + -viewDidDisapear:,因为它们总是被调用相同的次数。

答案 4 :(得分:0)

使用NSNotifications的最佳方法是在您需要观察通知时添加观察者在您不再需要时删除它们

这可以在viewDidLoad:viewWillAppear:上,或者当用户点按某个按钮等时。

我会给你一个小例子:

我的应用程序有一个标签栏,在某些视图控制器中,我正在显示从互联网下载的一些信息(例如推文)。我还有一个类池,用于每2分钟从服务器获取新数据,并且当服务器有新数据时,我更新了数据库上的信息。我不会使用委托模式来监听数据库更改,因为我有很多视图控制器显示数据,这将是一个非常糟糕的设计,使委托成为一个数组并循环传递每个视图控制器的数据。因此,在这种特定情况下,最好的办法是发布通知,告诉每个VC新数据的来源。

如果您的VC在视图消失时删除了委托,则只有当前视图会收到通知并更新显示内容。

您显然可以在显示之前更新其他VC的内容,例如viewWillAppear:,但这样做不仅在必要时更新VC内容,而且每次更改标签时都会更新。

这只是一个例子,我试图向您展示,对于NSNotifications,当我们没有关于您如何应用行为的完整描述时,很难建议您何时添加或删除观察者。