J'ai une classe C objective. Dans celui-ci, j'ai créé une méthode init et mis en place une NSNotification dedans
//Set up NSNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(getData)
name:@"Answer Submitted"
object:nil];
Où dois-je placer le [[NSNotificationCenter defaultCenter] removeObserver:self]
dans cette classe? Je sais que pour a UIViewController
, je peux l'ajouter dans la viewDidUnload
méthode Alors que faut-il faire si je viens de créer une classe objectif c?
-(void)dealloc
, puis l'ajouterremoveObserser:self
. C'est le moyen le plus recommandé de mettreremoveObservers:self
dealloc
méthode dans iOS 6?Réponses:
La réponse générique serait «dès que vous n’avez plus besoin des notifications». Ce n’est évidemment pas une réponse satisfaisante.
Je vous recommande d'ajouter un appel
[notificationCenter removeObserver: self]
à la méthodedealloc
de ces classes, que vous avez l'intention d'utiliser en tant qu'observateurs, car c'est la dernière chance de désinscrire proprement un observateur. Cependant, cela ne vous protégera que contre les plantages dus à la notification des objets morts par le centre de notification. Il ne peut pas protéger votre code contre la réception de notifications, lorsque vos objets ne sont pas encore / plus dans un état dans lequel ils peuvent gérer correctement la notification. Pour cela ... Voir ci-dessus.Modifier (puisque la réponse semble attirer plus de commentaires que je ne l'aurais pensé) Tout ce que j'essaie de dire ici, c'est: il est vraiment difficile de donner des conseils généraux sur le meilleur moment pour supprimer l'observateur du centre de notification, car cela dépend:
Donc, le meilleur conseil général que je puisse donner: protéger votre application. contre au moins un échec possible, faites la
removeObserver:
dansedealloc
, car c'est le dernier point (dans la vie de l'objet), où vous pouvez le faire proprement. Cela ne veut pas dire: "reporter simplement la suppression jusqu'à ce qu'elledealloc
soit appelée, et tout ira bien". Au lieu de cela, supprimez l'observateur dès que l'objet n'est plus prêt (ou requis) pour recevoir des notifications . C'est exactement le bon moment. Malheureusement, ne connaissant pas les réponses à aucune des questions mentionnées ci-dessus, je ne peux même pas deviner quand ce moment serait.Vous pouvez toujours en toute sécurité
removeObserver:
un objet plusieurs fois (et tous sauf le tout premier appel avec un observateur donné seront nops). Donc: pensez à le faire (à nouveau)dealloc
juste pour être sûr, mais avant tout: faites-le au moment approprié (qui est déterminé par votre cas d'utilisation).la source
dealloc
n'est qu'une dernière ligne de défense contre le plantage de l'application en raison d'un accès ultérieur à un objet décalloué. Mais le bon endroit pour désinscrire un observateur est généralement ailleurs (et souvent, beaucoup plus tôt dans le cycle de vie de l'objet). Je n'essaye pas de dire ici "Hé, fais-ledealloc
et tout ira bien".viewWillDisappear
" Le problème de donner un conseil concret est que cela dépend vraiment du type d'objet que vous enregistrez en tant qu'observateur pour quel type d'événement. Cela peut être la bonne solution pour désinscrire un observateur dansviewWillDisappear
(ouviewDidUnload
) pourUIViewController
s, mais cela dépend vraiment du cas d'utilisation.Remarque: cela a été testé et fonctionne à 100% pour cent
Rapide
PresentedViewController
Objectif c
Dans
iOS 6.0 > version
, il est préférable de supprimer l'observateurviewWillDisappear
car laviewDidUnload
méthode est obsolète.Il est souvent préférable de
remove observer
supprimer la vue dunavigation stack or hierarchy
.PresentedViewController
la source
viewWillAppear:
removeObserver:self
à l'un desUIViewController
événements du cycle de vie est presque garanti de ruiner votre semaine. More reading: subjectif-objective-c.blogspot.com/2011/04/…removeObserver
appelsviewWillDisappear
comme indiqué est certainement la bonne façon de procéder si le contrôleur est présenté viapushViewController
. Si vous les mettez à ladealloc
placedealloc
, vous ne serez jamais appelé - du moins d'après mon expérience ...Depuis iOS 9, il n'est plus nécessaire de supprimer les observateurs.
https://developer.apple.com/library/mac/releasenotes/Foundation/RN-Foundation/index.html#10_11NotificationCenter
la source
Si l'observateur est ajouté à un contrôleur de vue , je recommande fortement de l'ajouter
viewWillAppear
et de le supprimerviewWillDisappear
.la source
viewWillAppear
etviewWillDisappear
pour viewControllers?dealloc
l'appel immédiat. Revenir dans le contrôleur de vue peut alors provoquer plusieurs notifications si l'observateur est ajouté dans les commandes d'initialisation.la source
self
after[super dealloc]
me rend nerveux ... (même s'il est peu probable que le récepteur déréférencera le pointeur de quelque manière que ce soit, eh bien, on ne sait jamais comment ils ont mis en œuvreNSNotificationCenter
)[super dealloc]
doit toujours être la dernière déclaration de votredealloc
méthode. Il détruit votre objet; après son exécution, vous n'avezself
plus de fichier valide . / cc @Dirk[super dealloc]
n'est plus nécessaireEn général, je l'ai mis dans la
dealloc
méthode.la source
Dans swift use deinit car dealloc n'est pas disponible:
Documentation Swift:
la source
* modifier: Ce conseil s'applique à iOS <= 5 (même là, vous devriez ajouter
viewWillAppear
et supprimerviewWillDisappear
- cependant le conseil s'applique si pour une raison quelconque vous avez ajouté l'observateur dansviewDidLoad
)Si vous avez ajouté l'observateur dans,
viewDidLoad
vous devez le supprimer à la fois dansdealloc
etviewDidUnload
. Sinon, vous finirez par l'ajouter deux fois lors de l'viewDidLoad
appel aprèsviewDidUnload
(cela se produira après un avertissement de mémoire). Cela n'est pas nécessaire dans iOS 6 oùviewDidUnload
est obsolète et ne sera pas appelé (car les vues ne sont plus automatiquement déchargées).la source
À mon avis, le code suivant n'a aucun sens dans ARC :
Dans iOS 6 , il est également inutile de supprimer des observateurs
viewDidUnload
, car il est désormais obsolète.Pour résumer, je le fais toujours
viewDidDisappear
. Cependant, cela dépend également de vos besoins, tout comme @Dirk l'a dit.la source
Je pense avoir trouvé une réponse fiable ! Je devais le faire, car les réponses ci-dessus sont ambiguës et semblent contradictoires. J'ai parcouru les livres de cuisine et les guides de programmation.
Premièrement, le style de
addObserver:
inviewWillAppear:
etremoveObserver:
inviewWillDisappear:
ne fonctionne pas pour moi (je l'ai testé) car je publie une notification dans un contrôleur de vue enfant pour exécuter du code dans le contrôleur de vue parent. Je n'utiliserais ce style que si je postais et écoutais la notification dans le même contrôleur de vue.La réponse sur laquelle je vais le plus compter, j'ai trouvé dans la programmation iOS: Big Nerd Ranch Guide 4th. Je fais confiance aux gars de BNR car ils ont des centres de formation iOS et ils n'écrivent pas simplement un autre livre de cuisine. Il est probablement dans leur meilleur intérêt d'être précis.
Exemple 1 BNR:
addObserver:
dansinit:
,removeObserver:
dansdealloc:
Exemple BNR deux:
addObserver:
inawakeFromNib:
,removeObserver:
indealloc:
… Lors de la suppression de l'observateur,
dealloc:
ils n'utilisent pas[super dealloc];
J'espère que cela aidera la prochaine personne…
Je mets à jour cet article parce qu'Apple a maintenant presque complètement abandonné les Storyboards, donc ce qui précède peut ne pas s'appliquer à toutes les situations. La chose importante (et la raison pour laquelle j'ai ajouté ce message en premier lieu) est de faire attention si vous
viewWillDisappear:
êtes appelé. Ce n'était pas pour moi lorsque l'application est entrée en arrière-plan.la source
La réponse acceptée n'est pas sûre et pourrait provoquer une fuite de mémoire. S'il vous plaît laissez le désenregistrer dans dealloc mais aussi désenregistrer dans viewWillDisappear (c'est bien sûr si vous vous inscrivez dans viewWillAppear) .... C'EST CE QUE J'AI FAIT DE TOUTE MANIÈRE ET CELA FONCTIONNE BIEN! :)
la source
Il est important de noter également qu'il
viewWillDisappear
est également appelé lorsque le contrôleur de vue présente un nouvel UIView. Ce délégué indique simplement que la vue principale du contrôleur de vue n'est pas visible à l'écran.Dans ce cas, la désallocation de la notification dans
viewWillDisappear
peut être gênante si nous utilisons la notification pour permettre à UIview de communiquer avec le contrôleur de vue parent.En guise de solution, je supprime généralement l'observateur dans l'une de ces deux méthodes:
Pour des raisons similaires, lorsque j'émets la notification la première fois, je dois tenir compte du fait qu'à chaque fois qu'une vue apparaît au-dessus du contrôleur, la
viewWillAppear
méthode est déclenchée. Cela générera à son tour plusieurs copies de la même notification. Comme il n'y a pas de moyen de vérifier si une notification est déjà active, j'évite le problème en supprimant la notification avant de l'ajouter:la source
SWIFT 3
Il existe deux cas d'utilisation des notifications: - elles ne sont nécessaires que lorsque le contrôleur de vue est à l'écran; - ils sont toujours nécessaires, même si l'utilisateur a ouvert un autre écran sur courant.
Pour le premier cas, les emplacements corrects pour ajouter et supprimer un observateur sont:
pour le second cas, la manière correcte est:
Et jamais mis
removeObserver
endeinit{ ... }
- c'est une erreur!la source
la source