标签栏(视图控制器)中多次调用ios的通知中心方法方法?如何删除观察者?

Posted

技术标签:

【中文标题】标签栏(视图控制器)中多次调用ios的通知中心方法方法?如何删除观察者?【英文标题】:Notification center method method called multiple time ios in Tab bar (View controller)? How to remove observer? 【发布时间】:2015-11-06 11:37:47 【问题描述】:

我在标签栏应用程序的导航堆栈中发布通知表单一个视图控制器。我正在删除 dealloc 中的观察者。

 [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ArtworkAddedReloadAllArtworks" object:nil];  in dealloc correctly.

我正在注销

[[self tabBarController] dismissViewControllerAnimated:YES completion:nil];

但问题是当我重新登录时,在通知中心添加了两次相同的通知

ArtworkAddedReloadAllArtworks, 0x12ff698, 0x7a490e00, 1400
ArtworkAddedReloadAllArtworks, 0x12ff698, 0x7a431800, 1400

在通知中心创建了 2 个视图控制器实例,并且通知添加了两次两个不同的对象,我如何取消注册通知?我无法从 viewDidDisappear 中删除,因为我从其他控制器发布通知。dealloc 在登录后调用。

如何制作 nil 视图控制器(在登录前首先创建)和他的观察者?

提前致谢。

【问题讨论】:

显示添加观察者的代码。这会有所帮助。 我认为 dealloc 没有被调用。调试它来检查 [[NSNotificationCenter defaultCenter] addObserver:self 选择器:@selector(artworkAddedNotificationReceived:) name:@"ArtworkAddedReloadAllArtworks" object:nil];我重新登录后调用dealloc 你在哪里添加观察者? 在 viewDidLoad 方法的同一个类中。并从另一个班级发布通知。在我注销之前它工作正常。重新登录后,中心显示相同通知的 2 视图控制器如上所示。 ...请帮助我 【参考方案1】:
NSNotificationCenter.defaultCenter().removeObserver(self, name : UIKeyboardWillShowNotification, object: nil)

在这种情况下,任何侦听“UIKeyboardWillShowNotification”的观察者都将从您所在的视图控制器中删除。

【讨论】:

在你想移除观察者的地方调用这个,选择合适的名字。【参考方案2】:

如果发布类和观察类不同,我不能删除观察类中的观察者。

例如。在 A 类 viewWillAppear 中添加了调用观察者,现在我推送到 B 类,然后调用 A 类的 viewWillDisappear 并删除观察者现在通知不会被 A 类观察,因为它在推送操作时在 viewWillDisappear 中被删除。

我认为这不是正确的解决方案,但我最终通过保存观察者类引用并使用它来删除引用。

viewDidLoad方法中的A类(观察类)

  [[ASNGlobalClass shareManager] setNotificationSelf:self];//Save reference of self

B类(任何类)

[[NSNotificationCenter defaultCenter] removeObserver:[[ASNGlobalClass shareManager] notificationSelf]
                                                    name:@"LookbookChangeNotification"
                                                  object:nil];

【讨论】:

你真的需要在 ViewController A 不可见的时候观察它的一些变化吗?如果是这样,请使用我的答案中的解决方案 #2【参考方案3】:

请在界面生成器中查看reuseIdentifier。如果你设置它,UIViewController 可以多次调用viewDidLoad,并且只能调用一次 - dealloc。 请检查一下。

解决方案:

将添加/删除观察者移至viewWillAppearviewWillDisappear

- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someSelector:) name:@"ArtworkAddedReloadAllArtworks" object:nil];


- (void)viewWillDisappear:(BOOL)animated 
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ArtworkAddedReloadAllArtworks" object:nil];

另一种解决方案(我不喜欢它,但它可以提供帮助):

在添加观察者之前删除viewDidLoad 中的观察者

- (void)viewDidLoad 
    [super viewDidLoad];
    // Remove previously added observer to avoid of duplicate
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"ArtworkAddedReloadAllArtworks" object:nil];
    // Add new observer
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(someSelector:) name:@"ArtworkAddedReloadAllArtworks" object:nil];

【讨论】:

B 类发布通知,A 类是观察者,因此为 A 类或 B 类添加/删除观察者到 viewWillAppear 和 viewWillDisappear ?

以上是关于标签栏(视图控制器)中多次调用ios的通知中心方法方法?如何删除观察者?的主要内容,如果未能解决你的问题,请参考以下文章

如何处理标签栏的推送通知,我的标签栏控制器远离根视图控制器

如何访问标签栏控制器中的标签栏?

iOS - 收到推送通知后显示视图

ios标签栏点击显示模态视图黑屏

IOS Swift-收到推送通知时应用程序未打开特定选定的标签栏控制器索引

如何知道我之前在 iOS 中的标签栏视图控制器是哪个?