9

我有一个奇怪的问题,我注册了我的 iOS 应用程序来收听电话通讯录中的变化。当地址簿中的某些内容发生变化时会调用正确的方法,但它会被调用 2 到 6 次。

当对象被创建(单例,所以只有一个对象)时,我使用以下代码注册通知:

ABAddressBookRegisterExternalChangeCallback(notificationAddressBook, addressBookChanged, (__bridge_retained  void *)self);

调用的方法如下所示:

void addressBookChanged(ABAddressBookRef ab, CFDictionaryRef info, void *context){
ABAddressBookRevert(ab);

    NSLog(@"ADDRESSBOOK CHANGED");
    [phoneBookCopy updateCopy];
}

任何想法如何解决这个问题?

4

4 回答 4

3

尝试这个:

void addressBookChanged(ABAddressBookRef ab, CFDictionaryRef info, void *context){
ABAddressBookRevert(ab);

    NSLog(@"ADDRESSBOOK CHANGED");
    [phoneBookCopy updateCopy];
    CFRelease(ab);
}

这对我有帮助。

于 2014-06-03T11:35:50.440 回答
1

不久前我遇到了同样的问题,我不得不通过创建一个 NSTimer 来处理重复的回调来解决它:

[self.changeTimer invalidate];
self.changeTimer = nil;
self.changeTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                            target:self
                                                          selector:@selector(handleAdressBookExternalCallbackBackground)
                                                          userInfo:nil
                                                           repeats:NO];
于 2012-05-16T19:56:49.140 回答
0

我有一个类似的问题。第一次回调只会被调用一次,但是如果我第二次出去更改地址簿,那么它会被多次调用。对我来说,问题是ABAddressBookRegisterExternalChangeCallback在 appDelegate 的方法中调用的applicationWillResignActive:方法。

我使用地址簿的方式是用于同步设置。问题是,每次保存同步设置时,我都在注册外部回调,而不仅仅是在更改同步设置时。

为了说明,这是我在 appDelegate 中调用的代码

- (void)saveSettings
{
NSUserDefaults *syncSettingsData = [NSUserDefaults standardUserDefaults];
[syncSettingsData setObject:[NSNumber numberWithBool:self.isSyncingiPadContacts] forKey:SYNC_IPAD_CONTACTS_TURNED_ON];
[self setAddressBookChanged];
[syncSettingsData synchronize];
}

- (void)setAddressBookChanged
{
    if (self.isSyncingiPadContacts)
    {
        ABAddressBookRegisterExternalChangeCallback(self.addressBook, addressBookChanged, (__bridge void *)self);
    }
    else
    {
        ABAddressBookUnregisterExternalChangeCallback(self.addressBook, addressBookChanged, (__bridge void *) self);
    }
}

我删除了setAddressBookChanged方法中的调用saveSettings,只是在创建地址簿(第一次设置)以及用户更改同步设置时调用它。

希望这对您有所帮助。

于 2013-10-22T14:53:43.110 回答
0

我的解决方案非常简单,它不仅适用于此,而且适用于所有重复的回调(包括本地通知重复调用):我保留了最后一次调用时间的属性并检查时间间隔。希望它有所帮助,对我来说它完成了这项工作。

AppDelegate* 委托 = (__bridge AppDelegate*)context;

if (delegate.lastCall==nil) {
    delegate.lastCall = [[NSDate alloc]init];
}
else {
    NSTimeInterval interval = [[NSDate date] timeIntervalSinceDate:delegate.lastCall];
    if (interval<20) {
        return;
    }
    else {
        delegate.lastCall = [[NSDate alloc]init];
    }
}
于 2013-11-17T19:06:05.833 回答