ARC, laissez le charme agir... mais jusqu'à  quel point?

Bonjour,


 


Grand supporter (voire prosélyte) d'ARC, je me trouve confronté à  un problème engendré par lui.


 


J'ai un ViewController qui charge son nib à  la demande et l'insère dans la fenêtre principale de l'application. Il peut aussi désinstaller la vue, la retirer de la fenêtre.


 


Jusqu'ici tout va bien. La doc est claire:


 


- removeFromSuperview


Unlinks the receiver from its superview and its window, removes it from the responder chain, and invalidates its cursor rectangles.

The receiver is also released; if you plan to reuse it, be sure to retain it before sending this message and to release it as appropriate when adding it as a subview of another NSView.

Never invoke this method during display.

 

ça me paraà®t bien pensé. Après tout, si on remove, autant laisser tomber l'objet (si on veut le garder mais le faire disparaà®tre, il y a setHidden pour cela).

 

Or la vue du contrôleur possède des subviews. Et c'est là  que ça se gâte un peu...

 

En temps ordinaire, je me contreficherais de ce qui arrive aux subviews, ils seraient désalloués dans un cycle ou dans deux millions, grand bien leur fasse. Mais il se trouve que j'ai eu la bonne idée de faire de certains d'entre eux des abonnés au centre de notification...

 

Suivant l'idée proposée dans un autre sujet, je surcharge donc dealloc comme ceci:



- (void) dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

Mais voilà ... il devient maintenant crucial de savoir quand ma subview sera désallouée. Je ne tiens pas à  ce que des objets qui ne sont plus censés exister répondent à  des messages, et fassent appel à  d'autres objets jusqu'à  l'erreur fatale.


 


J'ai placé un NSLog dans ce dealloc, et inséré/retiré la vue du contrôleur 10'000 fois. Jamais un seul appel à  dealloc.


 


Comment résoudre ce petit problème?



 


Mots clés:

Réponses

  • jpimbertjpimbert Membre
    juin 2013 modifié #2

    Les sous-vues sont libérées mais pas forcément les contrôleurs de vue associés.


    Il est donc normal que le dealloc ne soit pas appelé sur le contrôleur de vue.


     


    Il y a donc quelques questions :


    - en quoi est-ce un problème que des messages soient envoyés à  un contrôleur de vue non affiché


    - à  quel moment se fait l'abonnement aux notifications


     


    La solution de "problème" (s'il y a effectivement un problème) dépend des réponses à  ces questions.


  • Merci pour cette réponse. C'est effectivement une autre occasion de plantage si le viewController fait référence à  sa propre view qui aurait été retirée à  un niveau supérieur, dans ce cas.


     


    Mais là , en l'occurrence, mon dealloc est dans une classe dérivée de NSView, pas de NSViewController.


  • FKDEVFKDEV Membre
    Ta vue a peut-être été retenue par un autre élément que sa superview.
    Un block ou autre.

    Tu peux essayer de surcharger retain et release pour debugger et mettre un breakpoint qui loggue les appels pour trouver qui fait le retain de trop.
  • AliGatorAliGator Membre, Modérateur
    Essaye aussi un coup de static analyzer qui pourrait te détecter des retain cycle (voire celui de LLVM 5 si t'as chopé Xcode5 DP, car celui de LLVM 5 est plus poussé sur le sujet)
  • Xcode5 DP... celle qui me bousille à  répétition mes fichiers xib? Oups. NDA.


Connectez-vous ou Inscrivez-vous pour répondre.