2013-08-23 20 views
5

Dodaję kontroler widoku jako obserwator do powiadomienia o UIKeyboardWillShowNotification.Obserwator nigdy nie zostanie usunięty z NSNotificationCenter

Mam ten kod w moim viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self 
            selector:@selector(keyboardWillShow:) 
             name:UIKeyboardWillShowNotification 
             object:nil]; 

i moim dealloc:

[[NSNotificationCenter defaultCenter] removeObserver:self]; 

Obserwator nie jest usuwany mimo dealloc jest wywoływana, gdy kontroler widoku jest zamknięta. Kiedy po raz drugi otworzę go, NSNotificationCenter spróbuje powiadomić stary obiekt, który został zwolniony, a aplikacja ulega awarii.

Widziałem kilka pytań tutaj na StackOverflow na temat tego konkretnego problemu, ale nie z odpowiedzi działa dla mnie.

Próbowałem usunąć obserwatora w viewWillDisappear i viewDidDisappear, ale ten sam problem występuje.

Używam ARC.

+0

nie używać "dealloc" z ARC –

+4

@Vaibhav źle. Dobrą praktyką jest używanie 'dealloc', po prostu nie można nazywać' [super dealloc] 'w implementacji –

+0

i mam taki sam problem jak ty, ale nie jestem w stanie znaleźć odpowiedniego rozwiązania, więc naprawiłem to wydać przez 'BOOL isFirstTime;', ustawić YES, gdy 'keyboardWillShow' i - (void) keyboardDidHide { if (!isFirstTime) return: ; , , , , , , isTxtFieldKeyBoard = NO; isFirstTime = NIE; } – iPatel

Odpowiedz

1

Czy wypróbowałeś dokładny fragment kodu w viewWillDisappear?

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self]; 
} 

Z twojego wyjaśnienia nie sądzę, że problem polega na usunięciu obserwatora. Spróbuj uruchomić obserwator z innego kontrolera viewcontroller. Jeśli nie zostanie uruchomiony, będziesz wiedział, że usunięcie zakończyło się sukcesem, a problem pojawia się, gdy dodajesz obserwatora po raz drugi.

+0

Tak, jak wspomniałem w moim pytaniu, spróbowałem. Zrobiłem to bez połączenia z super, ale to się nie różni, ponieważ domyślna implementacja nic nie robi. Spróbowałem tego, co zasugerowałeś tutaj, otwierając kontroler widoku raz, zamykając go, a następnie otwierając inny kontroler widoku, który ma 'UITextField'. Gdy tylko pojawiła się klawiatura, aplikacja zawiesiła się z komunikatem "*** - [NewTrackerViewController respondsToSelector:]: wiadomość wysłana do zwolnionej instancji 0xc14ac40". 'NewTrackerViewController' to taki, który nigdy nie wyrejestruje się jako obserwator. –

0

Może spróbuj określając parametr name, które zostały ustawione przed tak:

[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; 
0

Wygląda na to, że obserwator jest ustawiony coraz wielokrotnie. Czy kontroler jest odziedziczony po klasie, która również rejestruje to samo powiadomienie? Może to spowodować, że instancja kontrolera zostanie zarejestrowana jako obserwator więcej niż jeden raz. Jako obejście spróbować tego, w swojej klasie kontrolera gdzie dodać obserwatora,

// Remove as observer first 
[[NSNotificationCenter defaultCenter] removeObserver:self]; 
             name:UIKeyboardWillShowNotification 
             object:nil]; 
// Then add 
[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(keyboardWillShow:) 
             name:UIKeyboardWillShowNotification 
             object:nil]; 

To zapewni, że obserwator jest coraz dodany tylko jeden raz.

Nadzieję, że pomaga!

0
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"name" object:nil]; 

działa dobrze ze mną

Powiązane problemy