CNContactStoreDidChangeNotification запускается несколько раз
Я могу наблюдать CNContactStoreDidChangeNotification
когда база данных контактов изменяется, когда приложение находится в фоновом режиме. Я уверен, что только один наблюдатель был добавлен в NSNotificationCenter
, Проблема в NSNotificationCenter
сообщения несколько раз (2, 3, 5 и даже больше раз), даже если я добавлю только один новый контакт. В чем проблема?
3 ответа
Убедитесь, что вы не добавляете наблюдателя несколько раз. Это может произойти без вас, если вы, например, позвоните -addObserver
от -viewDidLoad
или же -viewDidAppear
в вашем контроллере представления (так как они могут вызываться более одного раза в течение жизни вашего приложения) или из любых обратных вызовов состояния приложения в вашем делегате приложения (-applicationDidBecomeActive
, -applicationWillResignActive
, -applicationDidEnterBackground
, -applicationWillEnterForeground
, так далее).
Оберните звонок -addObserver
в условии, гарантирующем, что он может быть вызван только один раз (установите флаг), и поместите вокруг него операторы NSLog, чтобы вы могли видеть в консоли отладки, если вы добираетесь туда более одного раза. Найдите свой код для других звонков на -addObserver
о котором вы могли забыть
Вызов -removeObserver
перед добавлением, просто чтобы быть уверенным (убедитесь, что передали то же имя и объект, что и при добавлении). призвание -removeObserver
на наблюдателя, который не существует, это нормально. Обратите внимание, что это скорее пластырь, чем исправление - ваш код должен быть достаточно умен, чтобы знать, добавили ли вы его или нет, но это может помочь вам диагностировать проблему).
Я только что написал минимальную тестовую программу, которая добавляет наблюдателя (один раз!) На CNContactStoreDidChangeNotification
и я получаю уведомление только один раз, когда добавляю или меняю контакт. Напишите аналогичную тестовую программу для себя и посмотрите, получите ли вы тот же результат. Если ваша тестовая программа работает правильно, то вполне вероятно, что ваше приложение делает то, чего вы не ожидаете (и вызывает -addObserver
многократно).
У меня была та же проблема, количество раз, когда оно срабатывало, варьировалось между 2 и 3. Решение, которое работало для меня, состояло в том, чтобы установить переменную семафора, установить в обработчике и сбросить семафор после завершения. Оберните обработку адресной книги в операторе if на семафоре, чтобы игнорировать дальнейшие вызовы. addressBkSemphore сбрасывается в false в buildFrendsAndContacts
- (void)addressBkChange:(NSNotification *)note
{
if (addressBkSemphore == false)
{
addressBkSemphore = TRUE;
[self buildFrendsAndContacts];
}
}
Надеюсь, поможет.
Вы можете запустить одноразовый таймер выполнения или диспетчеризацию через несколько секунд и отменить его, если в течение этих секунд будет обновлено новое контактное лицо, таким образом гарантируя, что только таймер или dispatch_after, инициированные последним обновлением, будут фактически выполняться (принимая во внимание, что все вызовы обновления приходят один за другим в пределах разницы секунд, насколько я проверял)
И, кстати, я мог воспроизвести проблему только при внесении изменений в контакты на одном устройстве с моим приложением. Если я меняю контакты на другом устройстве, связанном с той же учетной записью Apple, было только одно обновление.