У меня зарегистрирован обработчик обратного вызова, который прослушивает изменения в адресной книге iOS.По какой-то странной причине (по которой была подана ошибка) этот обратный вызов иногда может вызываться более одного раза, когда приложение возвращается из фона.Я хочу, чтобы мой обработчик обратного вызова выполнял свою логику только один раз, даже в тех случаях, когда обратный вызов вызывается несколько раз.Вот как я регистрирую обратный вызов:
ABAddressBookRegisterExternalChangeCallback(address_book, adressBookChanged, self);
Вот как я структурировал свой обработчик обратного вызова, чтобы использовать GCD для обработки этого.К сожалению, это не работает, и GCD не предотвращает двойной вызов внутренней логики ...
void adressBookChanged(ABAddressBookRef ab, CFDictionaryRef info, void
*context)
{
NSLog(@"** IN addressBookChanged callback!");
ABAddressBookUnregisterExternalChangeCallback (ab, adressBookChanged, context);
__block BOOL fireOnce = FALSE;
dispatch_queue_t queue;
queue = dispatch_queue_create("com.myapp.abcallback", NULL);
dispatch_async(queue, ^{
if (fireOnce == FALSE) {
fireOnce = TRUE;
dispatch_queue_t queueInternal;
queueInternal = dispatch_queue_create("com.myapp.abcallbackInternal", NULL);
dispatch_async (queueInternal, ^{
NSLog(@"do internal logic");
});
dispatch_release(queueInternal);
}
});
dispatch_release(queue);
}
Я почти уверен, что этот код работает для получения нескольких уведомлений, так что обратные вызовы отличаются?Они порождают разные потоки автоматически, делая значение fireOnce равным FALSE каждый раз?Как мне написать этот код, чтобы несколько обратных вызовов не вызывали внутреннюю логику более одного раза?Я полагаю, что я мог бы использовать блокировки и / или синхронизированные блоки для достижения этого, но GCD казался более чистым способом достижения этого.