28

当应用程序处于后台状态时,我能够观察到CNContactStoreDidChangeNotification联系人数据库何时更改。我很确定只有一名观察者被添加到NSNotificationCenter. 问题是NSNotificationCenter发布多次(2、3、5 甚至更多次),即使我只添加一个新联系人。问题出在哪里?

4

3 回答 3

4

确保您没有多次添加观察者。如果(例如)您-addObserver从视图控制器-viewDidLoad-viewDidAppear视图控制器中调用(因为这些可能在应用程序的整个生命周期中多次调用),或者从应用程序委托中的任何应用程序状态回调(-applicationDidBecomeActive, -applicationWillResignActive, -applicationDidEnterBackground,-applicationWillEnterForeground等)。

将调用包装-addObserver在一个条件中,确保它只能被调用一次(设置一个标志),并在它周围放置 NSLog 语句,这样你就可以在调试控制台中看到你是否多次到达那里。在您的代码中搜索您-addObserver可能忘记的其他调用。

在添加之前调用-removeObserver,只是为了确保(确保传递与添加时相同的名称和对象)。调用-removeObserver不存在的观察者是可以的。 请注意,这更像是一种创可贴而不是修复——你的代码应该足够聪明,可以知道你是否已经添加了它——但这可能有助于你诊断问题)。

我刚刚编写了一个快速的最小测试程序,它添加了一个观察者(一次!),CNContactStoreDidChangeNotification当我添加或更改联系人时,我只收到一次通知。为自己编写一个类似的测试程序,看看是否得到相同的结果。如果您的测试程序正常工作,那么您的应用程序很可能正在执行您不期望的事情(并且-addObserver多次调用)。

于 2017-04-26T17:56:34.627 回答
0

我遇到了同样的问题,它触发的次数在 2 和 3 之间变化。对我有用的解决方案是设置一个信号量变量,在处理程序中设置并在完成后重置信号量。将通讯簿处理包装在信号量的 if 语句中以忽略进一步的调用。addressBkSemphore 在 buildFrendsAndContacts 中重置为 false

- (void)addressBkChange:(NSNotification *)note
{   
    if (addressBkSemphore == false)
    {
        addressBkSemphore = TRUE;
        [self buildFrendsAndContacts];
    }
}

希望能帮助到你。

于 2017-07-12T09:30:00.037 回答
0

您可以在几秒钟后启动一次性执行计时器或调度并取消它,以防在那几秒钟内有新的联系人更新,从而确保只有最后一次更新触发的计时器或 dispatch_after 才会实际执行(考虑到所有据我测试,更新调用在一秒钟内一个接一个地出现。差异)

顺便说一句,只有在使用我的应用程序在同一设备上更改联系人时,我才能重现该问题。如果我更改链接到同一个苹果帐户的另一台设备上的联系人,则只有一个更新。

于 2018-01-13T19:13:06.457 回答