Я могу наблюдать за CNContactStoreDidChangeNotification
, когда база данных контактов изменена, когда приложение находится в фоновом режиме. Я уверен, что только один наблюдатель был добавлен в NSNotificationCenter
. Проблема NSNotificationCenter
сообщений МНОЖЕСТВЕННЫЕ времена (2, 3, 5 и даже больше раз), даже если я добавляю только один новый контакт. Где проблема?CNContactStoreDidChangeNotification запускается несколько раз
ответ
Убедитесь, что вы не добавляете наблюдателя несколько раз. Это может произойти, если вы не осознаете это, если (например) вы вызываете -addObserver
от -viewDidLoad
или -viewDidAppear
в вашем контроллере вида (поскольку они могут вызываться несколько раз в течение всего срока службы вашего приложения) или из любого из обратных вызовов состояния приложения в вашем делегат приложения (-applicationDidBecomeActive
, -applicationWillResignActive
, -applicationDidEnterBackground
, -applicationWillEnterForeground
и т. д.).
Оберните вызов -addObserver
в условном выражении, который гарантирует, что он может быть вызван только один раз (установить флаг), и поместить в него инструкции NSLog, чтобы вы могли видеть их в консоли отладки, если вы попадаете туда более одного раза. Найдите свой код для других звонков в -addObserver
, о которых вы, возможно, забыли.
Позвоните по номеру -removeObserver
, прежде чем добавлять его, чтобы быть уверенным (удостоверьтесь, что вы передаете одно и то же имя и объект, как при добавлении его). Вызов -removeObserver
на наблюдателя, который не существует, в порядке. Обратите внимание, что это скорее полоса, чем исправление - ваш код должен быть достаточно умным, чтобы знать, добавили ли вы его уже, но это может помочь вам диагностировать проблему).
Я написал небольшую тестовую программу, которая добавляет наблюдателя (один раз!) На CNContactStoreDidChangeNotification
, и я получаю уведомление только один раз, когда добавляю или меняю контакт. Напишите аналогичную тестовую программу для себя и посмотрите, получится ли у вас тот же результат. Если ваша тестовая программа работает правильно, то, скорее всего, ваше приложение делает то, чего вы не ожидаете (и несколько раз вызываете -addObserver
).
Вы пробовали его по большим контактным данным (например, я тестирую 500 контактов)? Я дважды проверил, что наблюдатель зарегистрирован только один раз (однотоновый, а в отладчике вы действительно можете его соблюдать). Тем не менее, я получаю 3 эха за каждое изменение контакта. Мое решение состояло в том, чтобы выполнить обработку изменений в фоновом режиме, и я перехожу к потоку в течение 3 секунд перед обработкой и отменяю операцию, если есть новое обновление. Таким образом, я гарантирую, что только последняя из «эха» будет обработана. BTW, в более старых iOSs я установил на 2 секунды сна, теперь с 10.3.3 я установил его на 3 секунды (как эхо, идущее позже) –
Наблюдение Джеффа очень хорошее и к делу. Это самая простая ошибка, которую можно было бы сделать, чтобы добавить наблюдателя несколько раз. Но проблема реальна, и это связано не с несколькими вызовами addObserver. Решение Ника может работать, но спать следует избегать. Вместо этого можно использовать таймер или dispatch_after, чтобы сделать трюк. – Bogdan
У меня была такая же проблема, количество раз, когда оно срабатывало, варьировалось между 2 & 3. Решение, которое работало для меня, состояло в том, чтобы установить переменную семафора, установленную в обработчике и сбросив семафор по завершении. Оберните обработку адресной книги в инструкции if на семафоре, чтобы игнорировать дальнейшие вызовы. addressBkSemphore сбрасываются на ложь в buildFrendsAndContacts
- (void)addressBkChange:(NSNotification *)note
{
if (addressBkSemphore == false)
{
addressBkSemphore = TRUE;
[self buildFrendsAndContacts];
}
}
Надеется, что это помогает.
Вы можете запустить одноразовый таймер выполнения или отправить его через несколько секунд и отменить его в случае, если в течение этих секунд произойдет новое обновление контактов, гарантируя тем самым, что только таймер или диспетчер_запроса, вызванные последним обновлением, будут фактически выполняться (принимая что все вызовы обновления происходят один за другим в пределах разницы в секундах, насколько я проверял)
И, кстати, я мог бы воспроизвести проблему только при изменении контактов на одном устройстве с моим приложением. Если я изменил контакты на другом устройстве, связанном с одной и той же учетной записью Apple, было только одно обновление.
Любые обновления по этому вопросу? – fancy
У меня также есть эта проблема. Даже в лучшем случае добавление контакта генерирует как минимум 2 уведомления CNContactStoreDidChangeNotification. Однако мои уведомления появляются только тогда, когда я возвращаюсь в свое приложение, но не в фоновом режиме. У кого-то еще есть эта проблема. –
У меня была аналогичная проблема с applicationDidBecomeActive на iPhone под управлением iOS 10, только в ландшафтном режиме. См.: http://stackoverflow.com/questions/39622392/applicationwillresignactive-called-without-reason-on-ios-10-swift-3 Я открыл новую ошибку в Apple Bug Reporter. Apple попросила меня более подробно, я отправил им свой полный проект Xcode ... но у меня не было никакого решения. Ошибка все еще открыта ... – Fox5150