当应用程序处于后台状态时,我能够观察到CNContactStoreDidChangeNotification
联系人数据库何时更改。我很确定只有一名观察者被添加到NSNotificationCenter
. 问题是NSNotificationCenter
发布多次(2、3、5 甚至更多次),即使我只添加一个新联系人。问题出在哪里?
3 回答
确保您没有多次添加观察者。如果(例如)您-addObserver
从视图控制器-viewDidLoad
或-viewDidAppear
视图控制器中调用(因为这些可能在应用程序的整个生命周期中多次调用),或者从应用程序委托中的任何应用程序状态回调(-applicationDidBecomeActive
, -applicationWillResignActive
, -applicationDidEnterBackground
,-applicationWillEnterForeground
等)。
将调用包装-addObserver
在一个条件中,确保它只能被调用一次(设置一个标志),并在它周围放置 NSLog 语句,这样你就可以在调试控制台中看到你是否多次到达那里。在您的代码中搜索您-addObserver
可能忘记的其他调用。
在添加之前调用-removeObserver
,只是为了确保(确保传递与添加时相同的名称和对象)。调用-removeObserver
不存在的观察者是可以的。 请注意,这更像是一种创可贴而不是修复——你的代码应该足够聪明,可以知道你是否已经添加了它——但这可能有助于你诊断问题)。
我刚刚编写了一个快速的最小测试程序,它添加了一个观察者(一次!),CNContactStoreDidChangeNotification
当我添加或更改联系人时,我只收到一次通知。为自己编写一个类似的测试程序,看看是否得到相同的结果。如果您的测试程序正常工作,那么您的应用程序很可能正在执行您不期望的事情(并且-addObserver
多次调用)。
我遇到了同样的问题,它触发的次数在 2 和 3 之间变化。对我有用的解决方案是设置一个信号量变量,在处理程序中设置并在完成后重置信号量。将通讯簿处理包装在信号量的 if 语句中以忽略进一步的调用。addressBkSemphore 在 buildFrendsAndContacts 中重置为 false
- (void)addressBkChange:(NSNotification *)note
{
if (addressBkSemphore == false)
{
addressBkSemphore = TRUE;
[self buildFrendsAndContacts];
}
}
希望能帮助到你。
您可以在几秒钟后启动一次性执行计时器或调度并取消它,以防在那几秒钟内有新的联系人更新,从而确保只有最后一次更新触发的计时器或 dispatch_after 才会实际执行(考虑到所有据我测试,更新调用在一秒钟内一个接一个地出现。差异)
顺便说一句,只有在使用我的应用程序在同一设备上更改联系人时,我才能重现该问题。如果我更改链接到同一个苹果帐户的另一台设备上的联系人,则只有一个更新。