代码之家  ›  专栏  ›  技术社区  ›  God of Biscuits

针对iOS/iPhone用户的关于重复通知观察的警告

  •  22
  • God of Biscuits  · 技术社区  · 14 年前

    与其说这是一个问题,不如说是一个警告,提醒其他人节省一些时间。

    iOS 3/iPhone OS 3上的NSNotificationCenter(我假设也是Mac OS X和iOS 4)具有以下行为:

    如果您多次注册以获得确切的特定通知,NSNotificationCenter将 不是 认识到冗余,相反,它会向您发送与您注册的观察次数相同的通知。

    例子:

    当新数据传入时,我希望我的视图控制器从单例网络对象接收通知:

    - (void) viewDidLoad 
    {
        [super viewDidLoad];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                selector:@selector(newDataArrived:) 
                    name:NewDataArrivedNotification
                  object:[NetworkListener sharedNetworkListener]];
    }
    

    但早些时候我已经把同样的东西放进去了 viewWillAppear :

    - (void) viewWillAppear
    {
        [super viewWillAppear];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                selector:@selector(newDataArrived:)
                    name:NewDataArrivedNotification
                  object:[NetworkListener sharedNetworkListener]];
    }
    

    确切地

    在这种情况下,如果我不删除这些addObserver调用中的一个,我将获得到视图控制器的重复通知。

    在多线程环境中,这是一个充满伤害的世界。相信我。

    3 回复  |  直到 12 年前
        1
  •  3
  •   God of Biscuits    11 年前

    如果您多次注册以获得确切的特定通知,NSNotificationCenter将 不是 认识到冗余,相反,它会向您发送与您注册的观察次数相同的通知。

    这几乎从来不是你想看到的行为,几乎总是偶然的。

    例子:

    - (void) viewDidLoad 
    {
        [super viewDidLoad];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                selector:@selector(newDataArrived:) 
                    name:NewDataArrivedNotification
                  object:[NetworkListener sharedNetworkListener]];
    }
    

    viewWillAppear :

    - (void) viewWillAppear
    {
        [super viewWillAppear];
    
        [[NSNotificationCenter defaultCenter] addObserver:self
                selector:@selector(newDataArrived:)
                    name:NewDataArrivedNotification
                  object:[NetworkListener sharedNetworkListener]];
    }
    

    注意它是 确切地 相同的通知,解析为相同的观察者、发送者和通知名称。

    在这种情况下,如果我不删除这些addObserver调用中的一个,我将获得到视图控制器的重复通知。

    在多线程环境中,这是一个充满伤害的世界。相信我。

        2
  •  2
  •   jakerz    12 年前


    最简单的方法是:[[NSNotificationCenter defaultCenter]removeObserver:self]
    在视图中放置AddObservators的好位置将出现,而RemoveObservators将消失。

        3
  •  0
  •   Nils Munch    12 年前

    正如您自己所说,NSNotificationCenter不检查重复项,这对某些人来说可能很烦人,但在协调其背后的完整系统时是有意义的。

    同样的逻辑也适用于向某些对象添加目标,但通常对这些对象有一个关键的识别。

    感谢您的洞察力,以及一个良好的,搜索引擎优化友好的警告:)