[英]ABAddressBookRegisterExternalChangeCallback called several times
我有一個奇怪的問題,我注冊了我的 iOS 應用程序以收聽電話通訊錄中的更改。 當地址簿中的某些內容發生變化但它被調用 2 - 6 次時,將調用正確的方法。
創建 object 時(單例,因此只有一個對象),我使用以下代碼注冊通知:
ABAddressBookRegisterExternalChangeCallback(notificationAddressBook, addressBookChanged, (__bridge_retained void *)self);
調用的方法如下所示:
void addressBookChanged(ABAddressBookRef ab, CFDictionaryRef info, void *context){
ABAddressBookRevert(ab);
NSLog(@"ADDRESSBOOK CHANGED");
[phoneBookCopy updateCopy];
}
任何想法如何解決這個問題?
試試這個:
void addressBookChanged(ABAddressBookRef ab, CFDictionaryRef info, void *context){
ABAddressBookRevert(ab);
NSLog(@"ADDRESSBOOK CHANGED");
[phoneBookCopy updateCopy];
CFRelease(ab);
}
這對我很有幫助。
我前一段時間遇到了同樣的問題,我不得不通過創建一個 NSTimer 來處理重復的回調來解決它:
[self.changeTimer invalidate];
self.changeTimer = nil;
self.changeTimer = [NSTimer scheduledTimerWithTimeInterval:3.0
target:self
selector:@selector(handleAdressBookExternalCallbackBackground)
userInfo:nil
repeats:NO];
我有一個類似的問題。 第一次只會調用一次回調,但如果我第二次出去修改通訊錄,就會調用多次。 對我來說,問題是在 appDelegate 的applicationWillResignActive:
方法中調用了持有ABAddressBookRegisterExternalChangeCallback
的方法。
我使用地址簿的方式是用於同步設置。 問題是,每次保存同步設置時我都在注冊外部回調,而不是僅在更改同步設置時注冊。
為了說明,這是我在 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);
}
}
我在saveSettings
方法中刪除了對setAddressBookChanged
的調用,只是在創建地址簿(第一次設置)和用戶更改同步設置時調用它。
希望這對你有幫助。
我的解決方案非常簡單並且有效,不僅適用於此,而且適用於所有重復的回調(包括本地通知重復調用):我保留一個包含上次調用時間的屬性並檢查時間間隔。 希望它有所幫助,對我來說它完成了工作。
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];
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.