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

问题描述 投票:23回答:5

我曾经在addObserverviewDidLoad:removeObserverdealloc:。码:

- (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];
}

但根据一些文章说,addObserverviewDidAppear:removeObserver更好。码:

viewDidDisappear:

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

iphone objective-c cocoa-touch
5个回答
21
投票

这取决于你的场景,通常最好的方法是添加- (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]; } 并删除viewDidLoaddealloc(在iOS 9.0中不推荐使用,仅使用viewDidUnload),但是在某些情况下,你在不同的类中使用相同的方法,如UI效果和想要使用通知只调用当前屏幕的方法,那么你必须在dealloc中添加观察者并在viewWillAppearviewWillDisappear / viewDidAppear中删除它

编辑:评论中的注释,谢谢@honey。

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


4
投票

我通常会把它放在Apple release notes-viewDidAppear:(或-viewDidDisapear:-viewWillAppear:)中,因为在我遇到的每种情况下,如果视图实际显示,我只对通知感兴趣。

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


1
投票

不要忘记NSKeyValueObservingOptionInitial。我在viewWillAppear / viewWillDisappear中使用它,所以我的UI始终是最新的,即使我隐藏了该视图控制器,也节省了资源,因为我不会更新它,直到再次显示。


0
投票

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

这可能是在-viewWillDisappear:viewDidLoad:,或当用户点击一些按钮等。

我会举一个小例子:

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

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

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

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


0
投票

viewWillAppear: + -viewWillAppear:-viewWillDisappear: + -viewDidAppear:更好,因为它们总是被称为相同的次数。

© www.soinside.com 2019 - 2024. All rights reserved.