2016-01-01 4 views
26

Я могу наблюдать за CNContactStoreDidChangeNotification, когда база данных контактов изменена, когда приложение находится в фоновом режиме. Я уверен, что только один наблюдатель был добавлен в NSNotificationCenter. Проблема NSNotificationCenter сообщений МНОЖЕСТВЕННЫЕ времена (2, 3, 5 и даже больше раз), даже если я добавляю только один новый контакт. Где проблема?CNContactStoreDidChangeNotification запускается несколько раз

+0

Любые обновления по этому вопросу? – fancy

+0

У меня также есть эта проблема. Даже в лучшем случае добавление контакта генерирует как минимум 2 уведомления CNContactStoreDidChangeNotification. Однако мои уведомления появляются только тогда, когда я возвращаюсь в свое приложение, но не в фоновом режиме. У кого-то еще есть эта проблема. –

+0

У меня была аналогичная проблема с applicationDidBecomeActive на iPhone под управлением iOS 10, только в ландшафтном режиме. См.: http://stackoverflow.com/questions/39622392/applicationwillresignactive-called-without-reason-on-ios-10-swift-3 Я открыл новую ошибку в Apple Bug Reporter. Apple попросила меня более подробно, я отправил им свой полный проект Xcode ... но у меня не было никакого решения. Ошибка все еще открыта ... – Fox5150

ответ

4

Убедитесь, что вы не добавляете наблюдателя несколько раз. Это может произойти, если вы не осознаете это, если (например) вы вызываете -addObserver от -viewDidLoad или -viewDidAppear в вашем контроллере вида (поскольку они могут вызываться несколько раз в течение всего срока службы вашего приложения) или из любого из обратных вызовов состояния приложения в вашем делегат приложения (-applicationDidBecomeActive, -applicationWillResignActive, -applicationDidEnterBackground, -applicationWillEnterForeground и т. д.).

Оберните вызов -addObserver в условном выражении, который гарантирует, что он может быть вызван только один раз (установить флаг), и поместить в него инструкции NSLog, чтобы вы могли видеть их в консоли отладки, если вы попадаете туда более одного раза. Найдите свой код для других звонков в -addObserver, о которых вы, возможно, забыли.

Позвоните по номеру -removeObserver, прежде чем добавлять его, чтобы быть уверенным (удостоверьтесь, что вы передаете одно и то же имя и объект, как при добавлении его). Вызов -removeObserver на наблюдателя, который не существует, в порядке. Обратите внимание, что это скорее полоса, чем исправление - ваш код должен быть достаточно умным, чтобы знать, добавили ли вы его уже, но это может помочь вам диагностировать проблему).

Я написал небольшую тестовую программу, которая добавляет наблюдателя (один раз!) На CNContactStoreDidChangeNotification, и я получаю уведомление только один раз, когда добавляю или меняю контакт. Напишите аналогичную тестовую программу для себя и посмотрите, получится ли у вас тот же результат. Если ваша тестовая программа работает правильно, то, скорее всего, ваше приложение делает то, чего вы не ожидаете (и несколько раз вызываете -addObserver).

+0

Вы пробовали его по большим контактным данным (например, я тестирую 500 контактов)? Я дважды проверил, что наблюдатель зарегистрирован только один раз (однотоновый, а в отладчике вы действительно можете его соблюдать). Тем не менее, я получаю 3 эха за каждое изменение контакта. Мое решение состояло в том, чтобы выполнить обработку изменений в фоновом режиме, и я перехожу к потоку в течение 3 секунд перед обработкой и отменяю операцию, если есть новое обновление. Таким образом, я гарантирую, что только последняя из «эха» будет обработана. BTW, в более старых iOSs я установил на 2 секунды сна, теперь с 10.3.3 я установил его на 3 секунды (как эхо, идущее позже) –

+0

Наблюдение Джеффа очень хорошее и к делу. Это самая простая ошибка, которую можно было бы сделать, чтобы добавить наблюдателя несколько раз. Но проблема реальна, и это связано не с несколькими вызовами addObserver. Решение Ника может работать, но спать следует избегать. Вместо этого можно использовать таймер или dispatch_after, чтобы сделать трюк. – Bogdan

0

У меня была такая же проблема, количество раз, когда оно срабатывало, варьировалось между 2 & 3. Решение, которое работало для меня, состояло в том, чтобы установить переменную семафора, установленную в обработчике и сбросив семафор по завершении. Оберните обработку адресной книги в инструкции if на семафоре, чтобы игнорировать дальнейшие вызовы. addressBkSemphore сбрасываются на ложь в buildFrendsAndContacts

- (void)addressBkChange:(NSNotification *)note 
{ 
    if (addressBkSemphore == false) 
    { 
     addressBkSemphore = TRUE; 
     [self buildFrendsAndContacts]; 
    } 
} 

Надеется, что это помогает.

0

Вы можете запустить одноразовый таймер выполнения или отправить его через несколько секунд и отменить его в случае, если в течение этих секунд произойдет новое обновление контактов, гарантируя тем самым, что только таймер или диспетчер_запроса, вызванные последним обновлением, будут фактически выполняться (принимая что все вызовы обновления происходят один за другим в пределах разницы в секундах, насколько я проверял)

И, кстати, я мог бы воспроизвести проблему только при изменении контактов на одном устройстве с моим приложением. Если я изменил контакты на другом устройстве, связанном с одной и той же учетной записью Apple, было только одно обновление.