GCD и обратные вызовы - проблема параллелизма

У меня зарегистрирован обработчик обратного вызова, который прослушивает изменения в адресной книге 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 казался более чистым способом добиться этого.

6
задан Z S 19 August 2011 в 04:30
поделиться