2016-01-01 25 views
26

Jestem w stanie zaobserwować CNContactStoreDidChangeNotification, gdy baza danych kontaktów zostanie zmieniona, gdy aplikacja jest w tle. Jestem pewien, że tylko jeden obserwator został dodany do NSNotificationCenter. Problem dotyczy wpisów NSNotificationCenter WIELE razy (2, 3, 5, a nawet więcej razy), nawet jeśli dodaję tylko jeden nowy kontakt. Gdzie jest problem?CNContactStoreDidChangeNotification jest uruchamiany wiele razy

+0

Wszelkie aktualizacje w tej sprawie? – fancy

+0

Mam również ten problem. Nawet w najlepszym przypadku dodanie kontaktu generuje co najmniej 2 powiadomienia CNContactStoreDidChangeNotification. Jednak moje powiadomienia pojawiają się dopiero po powrocie do mojej aplikacji, ale nie w tle. Ktoś jeszcze ma ten problem. –

+0

Miałem podobny problem z applicationDidBecomeActive na iPhone'a z systemem iOS 10, tylko w trybie poziomym. Proszę zobaczyć: http://stackoverflow.com/questions/39622392/applicationwillresignactive-called-without-reason-on-ios-10-swift-3 Otworzyłem nowy błąd w Apple Bug Reporter. Apple poprosił mnie o więcej szczegółów, wysłałem im mój kompletny projekt Xcode ... ale nie miałem rozwiązania. Błąd nadal jest otwarty ... – Fox5150

Odpowiedz

4

Upewnij się, że nie dodajesz obserwatora wiele razy. Może się tak zdarzyć, gdy nie zdasz sobie z tego sprawy, jeśli (na przykład) zadzwonisz pod numer -addObserver z kontrolera widoku (ponieważ mogą one zostać wywołane więcej niż raz przez cały okres użytkowania aplikacji) lub z dowolnego stanu zwrotnego stanu aplikacji w twoim delegat aplikacji (-applicationDidBecomeActive, -applicationWillResignActive, -applicationDidEnterBackground, -applicationWillEnterForeground itd.).

Zawiń połączenie do -addObserver w trybie warunkowym, który zapewnia, że ​​można go wywołać tylko raz (ustawić flagę) i umieścić w nim instrukcje NSLog, aby można było zobaczyć w konsoli debugowania, czy pojawia się tam więcej niż raz. Wyszukaj w swoim kodzie inne połączenia pod numer -addObserver, o których mógłbyś zapomnieć.

Zadzwoń pod -removeObserver przed dodaniem, aby mieć pewność (upewnij się, że przekazałeś tę samą nazwę i obiekt, co przy dodaniu). Dzwonienie pod numer -removeObserver do obserwatora, który nie istnieje, jest w porządku. Należy pamiętać, że jest to raczej pomoc zespołu niż poprawka - kod powinien być wystarczająco inteligentny, aby wiedzieć, czy już go dodałeś, ale może to pomóc w zdiagnozowaniu problemu).

Właśnie napisałem program szybkiego minimalnego testu, który dodaje obserwatora (raz!) Na CNContactStoreDidChangeNotification i otrzymuję powiadomienie tylko raz, gdy dodaję lub zmieniam kontakt. Napisz podobny program testowy dla siebie i zobacz, czy uzyskasz taki sam wynik. Jeśli Twój program testowy działa poprawnie, prawdopodobnie aplikacja robi coś, czego się nie spodziewasz (i wielokrotnie wywołuje -addObserver).

+0

Czy wypróbowałeś to na dużych kontaktach (jak testuję na ponad 500 kontaktach)? Sprawdziłem dwukrotnie, czy obserwator jest zarejestrowany tylko raz (jest on jednokolorowy, aw debugerze naprawdę można go śledzić). Mimo to otrzymuję 3 echa za każdą zmianę kontaktu. Moim rozwiązaniem było przetwarzanie zmian w tle, a ja przełączyłem wątek w stan uśpienia na 3 s przed przetworzeniem i anulowanie operacji, jeśli pojawi się nowa aktualizacja. Zapewniam więc, że tylko najnowsze z "echa" będą przetwarzane. BTW, w starszych iOSs ustawiłem na 2 sekundy snu, teraz z 10.3.3 ustawiłem to na 3 sekundy (jak echo nadchodzi później) –

+0

Obserwacja Jeffa jest bardzo dobra i na temat. To najłatwiejszy błąd, jaki można zrobić, aby dodać obserwatora wielokrotnie. Ale problem jest prawdziwy i nie wynika z wielu wywołań funkcji addObserver. Rozwiązanie Nicka może zadziałać, ale należy unikać snu. Zamiast tego można użyć zegara lub dispatch_after, aby zrobić lewę. – Bogdan

0

miałem ten sam problem, ile razy on zwolniony zróżnicowane pomiędzy 2 & 3. Roztwór, który pracował dla mnie było ustawić zmienną semafor ustawiony w uchwycie i zresetować semafora po zakończeniu. Zawiń przetwarzanie książki adresowej w instrukcji if na semaforze, aby ignorować kolejne wywołania. addressBkSemphore jest resetowany false w buildFrendsAndContacts

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

Nadzieję, że to pomaga.

0

Możesz uruchomić jednorazowy licznik czasu wykonania lub wysyłkę po kilku sekundach i anulować w przypadku, gdy w ciągu kilku sekund nastąpi aktualizacja nowych kontaktów, dzięki czemu tylko timer lub funkcja dispatch_after uruchomiona przez ostatnią aktualizację będzie faktycznie wykonywana (pobieranie biorąc pod uwagę, że wszystkie wywołania aktualizacji przychodzą jedna po drugiej w ramach różnicy sekundowej, o ile testowałem)

I przy okazji mogłem odtworzyć problem tylko przy zmianie kontaktów na tym samym urządzeniu z moją aplikacją. Jeśli zmienię kontakty na innym urządzeniu połączonym z tym samym kontem Apple, była tylko jedna aktualizacja.

Powiązane problemy