Ios CNContactStoreDidChangeNotification被多次激发

Ios CNContactStoreDidChangeNotification被多次激发,ios,swift,nsnotificationcenter,cncontact,cncontactstore,Ios,Swift,Nsnotificationcenter,Cncontact,Cncontactstore,当联系人数据库在应用程序处于后台状态时发生更改时,我能够观察到CNContactStoreDidChangeNotification。我敢肯定,只有一名观察员被添加到了NSNotificationCenter。 问题是NSNotificationCenter发布多次(2次、3次、5次甚至更多次),即使我只添加了一个新联系人。 问题出在哪里?确保没有多次添加观察者。如果(例如)您从视图控制器中的-viewdiload或-viewdirebeen调用-addObserver(因为在应用程序的整个生命

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

确保没有多次添加观察者。如果(例如)您从视图控制器中的
-viewdiload
-viewdirebeen
调用
-addObserver
(因为在应用程序的整个生命周期中,它们可能会被多次调用),或者从应用程序委托中的任何应用程序状态回调调用,则可能会发生这种情况(
-applicationIDBecomeActive
-applicationWillResignActive
-applicationIdentinterBackground
-applicationWillEnterForeground
等)

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

在添加之前调用
-removeObserver
,以确保(确保传递与添加时相同的名称和对象)在一个不存在的观察者上调用<代码> -ReaveValue。<强>注意这是一个创可贴,而不是一个补丁——你的代码应该足够聪明,知道你是否已经添加了它——但是这可能有助于你诊断问题。< <强> >/P>
我刚刚编写了一个快速的最小测试程序,在
CNContactStoreDidChangeNotification
上添加了一个观察者(一次!),当我添加或更改联系人时,我只收到一次通知。为自己编写一个类似的测试程序,看看是否得到相同的结果。如果您的测试程序工作正常,那么很可能您的应用程序正在做一些您不期望的事情(并且多次调用
-addObserver)。

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

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

希望有帮助。

您可以在几秒钟后启动一次性执行计时器或调度,并在几秒钟内更新新联系人时取消它,从而确保只有上次更新触发的计时器或调度才会真正执行(考虑到就我所测试的而言,所有更新调用都是在一秒差内一个接一个地进行的)


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

有此更新吗?我也有此问题。即使在最好的情况下,添加联系人也会生成至少2个CNContactStoredChangeNotifi阳离子通知。但是,我的通知只在我返回应用程序时出现,而不是在后台。其他人都有此问题。我在运行iOS 10的iPhone上的ApplicationIDBecMeactive也有类似问题,只是在横向模式下。请参阅:我在Apple bug Reporter中打开了一个新的bug。Apple问我更多详细信息,我向他们发送了我完整的Xcode项目…但我没有解决方案。错误仍然存在…我认为没有问题。如果您查看从较旧的
KABDatabaseChangedTernallyNotification
触发的通知中的userInfo字典,您将看到该通知实际上是从一个或多个
ABSenderProcessNames,如Contacts.app和AddressBookSourceSync。如果您尝试从手机更新联系人,您将收到来自AddressBookSourceSync的一条通知。您是否在大联系人数据上尝试过(如我正在测试500多个联系人)?我再次检查了该观察员是否只注册了一次(这是单音,在调试器中,你可以真正遵循它)。然而,我每次更改联系人都会收到3个回音。我的解决方案是在后台处理更改,在处理之前我将线程转入睡眠状态3秒钟,如果有新的更新,则取消操作。因此,我只确保“回音”中的最新内容将被处理。顺便说一句,在较旧的IOS中,我设置为2秒睡眠,现在使用10.3.3,我将其设置为3秒(稍后将出现回声)Jeff的观察非常好,切中要害。这是一个人可能犯的最容易的错误,多次添加观察者。但问题是真实的,它不是由于多次调用addObserver造成的。Nick的解决方案可能有效,但应该避免睡眠。相反,可以使用计时器或调度来完成此操作。解决方案是rs建议在处理更改之前暂停,这似乎更好,因为这意味着使用了最新版本的通讯簿(如果两个更改发生在一起-例如,如果有人在脱机时在另一台设备上进行了一些编辑,然后连接到wifi)