Fondamentalement, j'ai un view1 qui, à un moment donné, appelle view2 (via presentModalViewController:animated:
). Lorsqu'un certain UIButton
dans view2 est enfoncé, view2 is appelle une méthode de notification dans view1 et immédiatement après il est ignoré. La méthode de notification fait apparaître une alerte.
La méthode de notification fonctionne correctement et est appelée de manière appropriée. Le problème est que chaque fois que view1 est créé (une seule view1 doit exister à la fois), j'obtiens probablement un autre NSNotification
en cours de création car si je passe de view0 (le menu) à view1, quelques fois, j'obtiens une série du même message d'alerte, l'un après l'autre, de la méthode de notification autant de fois que j'ai ouvert une vue1.
Voici mon code, dites-moi ce que je fais mal:
View1.m
-(void) viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(showAlert:)
name:@"alert"
object:nil];
}
-(void) showAlert:(NSNotification*)notification {
// (I've also tried to swap the removeObserver method from dealloc
// to here, but it still fails to remove the observer.)
// < UIAlertView code to pop up a message here. >
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
View2.m
-(IBAction) buttonWasTapped {
[[NSNotificationCenter defaultCenter] postNotificationName:@"alert"
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
-(void) dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
Appeler -dealloc
ne se produit pas automatiquement après le rejet du contrôleur de vue - il peut encore y avoir une certaine "durée de vie" dans la durée de vie du contrôleur de vue. Dans ce délai, ce contrôleur de vue est toujours abonné à cette notification.
Si vous supprimez l'observateur dans -viewWillDisappear:
ou -viewDidDisappear:
, cela aura un effet plus immédiat:
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self
name:@"alert"
object:nil];
}
Si vous implémentez la suppression d'Observer dans le viewWillDisappear:
ou viewDidDisappear:
alors vous ne devez pas laisser l'addition de l'observateur dans le viewDidLoad
.
Mettez plutôt l'ajout de l'observateur dans le viewWillAppear:
. Le problème que vous rencontrez est que, lorsqu'une vue est affichée sur la vue UIViewController
, la suppression de votre observateur se produit et puisque vous avez ajouté l'observateur dans viewDidLoad
, ce qui ne se produira qu'une seule fois, ce sera perdu.
Gardez à l'esprit que cette approche fonctionne bien pour les objets que vous ne souhaitez pas observer alors que votre vue principale n'est pas à l'avant.
Gardez également à l'esprit que viewDidUnload
a également été amorti.
Il n'y a rien de mal à mettre removeObserver:
dans dealloc
. Le simple fait qu'il ne soit pas appelé signifie que view1 n'est pas correctement libéré après le rejet. On dirait que quelque chose détient un pointeur sur votre vue1, vérifiez les cycles de conservation.
De plus, vous ne devriez pas appeler dealloc sur super.