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

fan*_*ard 23 iphone cocoa-touch objective-c

我曾经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];
}
Run Code Online (Sandbox Code Playgroud)

但据一些文章说,最好是addObserverviewDidAppear:removeObserverviewDidDisappear:.码:

- (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];
}
Run Code Online (Sandbox Code Playgroud)

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

Saa*_*aad 21

这取决于您的场景,通常最好的方法是添加viewDidLoad和删除in dealloc和in viewDidUnload,但是在某些情况下,当您在不同的类中使用相同的方法(如UI效果)并且想要使用通知仅调用当前屏幕的方法时,那么您将必须添加观察者dealloc并将其删除viewWillAppearviewWillDisappear/viewDidAppear

  • 我认为第一个解决方案不是最好的,因为可能存在类被引入但视图未加载的情况.应用程序将崩溃并显示错误"无法从<OBJ 0x111bc890>中删除关键路径"KEY_PATH"的观察者<CustomViewController 0xbbc19c0>,因为它未注册为观察者." (7认同)
  • @DanSkeel如果你有这样的场景可能那么它可能意味着`viewDidLoad`不是你应该写观察者的地方.每个业务/ UI要求都应该有自己适当的周期.虽然现在**自iOS 9**以来,您不再需要关心移除观察者.请参阅[Apple发行说明](https://developer.apple.com/library/content/releasenotes/Foundation/RN-FoundationOlderNotes/index.html):"在OS X 10.11和iOS 9.0中,NSNotificationCenter和NSDistributedNotificationCenter将不再发送通知对可能被解除分配的注册观察员......" (4认同)
  • @DanSkeel可能会添加`init`和`awakeFormNib`? (2认同)
  • 好吧,如果您需要更新 rootviewcontroller 或堆栈中当前视图控制器之前的任何视图控制器中的某个日期,如果您使用 viewWillAppear/Disappear,您的通知将不会被触发到前一个视图控制器。正如问题中提到的,这取决于场景 (2认同)