Avertissement pour les utilisateurs iOS / iPhone sur les observations en double NSNotification
-
28-09-2019 - |
Question
Ce n'est pas une question tant d'avertissement aux autres pour les sauver du temps.
NSNotificationCenter sur iOS 3 / iPhone OS 3 (je suppose aussi Mac OS X et iOS 4) a le comportement suivant:
Si vous vous inscrivez à plusieurs reprises pour la notification spécifique exacte, NSNotificationCenter sera pas reconnaître la redondance et à la place déclencher autant de notifications pour vous que vous avez enregistré une observation pour.
Ceci est presque jamais le comportement que vous voulez voir et est presque toujours accidentelle.
Exemple:
Je veux que mon contrôleur de vue de recevoir des notifications d'un objet réseau singleton lorsque de nouvelles données est disponible en:
- (void) viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
mais plus tôt, je l'avais déjà posé la même chose en viewWillAppear
:
- (void) viewWillAppear
{
[super viewWillAppear];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
Notez qu'il est exactement la même notification, la résolution au même observateur, l'expéditeur et le nom notification.
Dans ce cas, si je ne retire pas un de ces appels addObserver, je vais recevoir des notifications en double à mon contrôleur de vue.
Dans un environnement multi-thread, c'est un monde de souffrance. Croyez-moi.
Il suffit de mettre ce là-bas dans le cas où il y a d'autres qui se jettent dans quelque chose comme ça.
La solution
NSNotificationCenter sur iOS 3 / iPhone OS 3 (je suppose aussi Mac OS X et iOS 4) a le comportement suivant:
Si vous vous inscrivez à plusieurs reprises pour la notification spécifique exacte, NSNotificationCenter sera pas reconnaître la redondance et à la place déclencher autant de notifications pour vous que vous avez enregistré une observation pour.
Ceci est presque jamais le comportement que vous voulez voir et est presque toujours accidentelle.
Exemple:
Je veux que mon contrôleur de vue de recevoir des notifications d'un objet réseau singleton lorsque de nouvelles données est disponible en:
- (void) viewDidLoad
{
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
mais plus tôt, je l'avais déjà posé la même chose en viewWillAppear
:
- (void) viewWillAppear
{
[super viewWillAppear];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(newDataArrived:)
name:NewDataArrivedNotification
object:[NetworkListener sharedNetworkListener]];
}
Notez qu'il est exactement la même notification, la résolution au même observateur, l'expéditeur et le nom notification.
Dans ce cas, si je ne retire pas un de ces appels addObserver, je vais recevoir des notifications en double à mon contrôleur de vue.
Dans un environnement multi-thread, c'est un monde de souffrance. Croyez-moi.
Il suffit de mettre ce là-bas dans le cas où il y a d'autres qui se jettent dans quelque chose comme ça.
Autres conseils
Vous devriez toujours nettoyer vos observateurs.
La façon de le faire est plus facile: [[NSNotificationCenter defaultCenter] removeObserver: auto]
viewDidLoad n'est pas un bon endroit pour ajouter des observateurs, parce que ces fonctions peuvent s'appeler plusieurs fois, cela se produit lorsque viewDidUnload est déclenchée.
Un bon endroit pour mettre vos addObservers à viewWillAppear et removeObservers dans viewWillDisappear.
Comme vous l'avez dit, NSNotificationCenter ne fait aucune vérification des doublons, ce qui peut être gênant pour certains, mais est logique quand concidering le système complet derrière.
La même logique vaut pour ajouter des cibles à certains objets, mais il y a souvent une reconnaissance de clé sur ceux-ci.
Je vous remercie de la perspicacité, et pour un bon avertissement convivial SEO:)