我曾经在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:
那么,addObserver / removeObserver更好的方法是什么?
这取决于你的场景,通常最好的方法是添加- (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];
}
并删除viewDidLoad
和dealloc
(在iOS 9.0中不推荐使用,仅使用viewDidUnload
),但是在某些情况下,你在不同的类中使用相同的方法,如UI效果和想要使用通知只调用当前屏幕的方法,那么你必须在dealloc
中添加观察者并在viewWillAppear
或viewWillDisappear
/ viewDidAppear
中删除它
编辑:评论中的注释,谢谢@honey。
虽然现在从iOS 9开始,你不再需要关心移除观察者了。请参阅viewDidDisappear
:“在OS X 10.11和iOS 9.0中,NSNotificationCenter和NSDistributedNotificationCenter将不再向可能已解除分配的已注册观察者发送通知。
我通常会把它放在Apple release notes和-viewDidAppear:
(或-viewDidDisapear:
和-viewWillAppear:
)中,因为在我遇到的每种情况下,如果视图实际显示,我只对通知感兴趣。
这可能是一个过早的优化(你的代码处理通知可能需要一些时间,但如果没有显示视图可能会没用),但它也没有更多的代码 - 只是在不同的方法中它是相同的代码...
不要忘记NSKeyValueObservingOptionInitial。我在viewWillAppear / viewWillDisappear中使用它,所以我的UI始终是最新的,即使我隐藏了该视图控制器,也节省了资源,因为我不会更新它,直到再次显示。
使用NSNotifications的最佳方法是在需要观察通知时添加观察者,并在不再需要时删除它们。
这可能是在-viewWillDisappear:
,viewDidLoad:
,或当用户点击一些按钮等。
我会举一个小例子:
我的应用程序有一个标签栏,在一些视图控制器中,我正在显示从互联网下载的一些信息(例如推文)。我还有一个类池,用于每2分钟从服务器获取新数据,并且当服务器有新数据时,我更新了数据库上的信息。我不会使用委托模式来监听数据库更改,因为我有很多视图控制器显示数据,这将是一个非常糟糕的设计,使委托成为一个数组并循环传递每个视图控制器的数据。因此,在这种特定情况下,最好的办法是发布通知,告诉每个VC新数据的来源。
如果VC在视图消失时删除了委托,则只有当前视图将接收通知并更新显示内容。
您显然可以在显示之前更新其他VC的内容,例如在viewWillAppear:
上,但这样做VC内容不仅会在必要时更新,而且每次更改选项卡时都会更新。
这只是一个例子,我试图告诉你,对于NSNotifications,当我们没有关于你如何应用行为的完整描述时,很难建议你何时添加或删除观察者。
viewWillAppear:
+ -viewWillAppear:
比-viewWillDisappear:
+ -viewDidAppear:
更好,因为它们总是被称为相同的次数。