多次调用ABAddressBookRegisterExternalChangeCallback

时间:2012-04-10 21:07:38

标签: iphone ios abaddressbook

我有一个奇怪的问题,我注册我的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 个答案:

答案 0 :(得分:3)

试试这个:

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

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

这对我有帮助。

答案 1 :(得分:1)

前一段时间我遇到了同样的问题,我必须通过创建NSTimer来解决它,以处理重复的回调:

[self.changeTimer invalidate];
self.changeTimer = nil;
self.changeTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
                                                            target:self
                                                          selector:@selector(handleAdressBookExternalCallbackBackground)
                                                          userInfo:nil
                                                           repeats:NO];

答案 2 :(得分:0)

我有类似的问题。回调只会在第一次调用时调用,但是如果我第二次调出并更改了地址簿,那么它将被多次调用。 对我来说,问题是在appDelegate' ABAddressBookRegisterExternalChangeCallback方法中调用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的调用,只是在创建地址簿时(第一次设置)以及用户更改同步设置时调用了它。

希望这可以帮到你。

答案 3 :(得分:0)

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

AppDelegate * delegate =(__ 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];
    }
}