Quelques subtilités sur la gestion mémoire

2»

Réponses

  • 20:31 modifié #32
    J'aurai tendance, par habitude, à  foutre ton internalValue à  nil aussi dans le dealloc.
  • AliGatorAliGator Membre, Modérateur
    20:31 modifié #33
    A noter, si vous ne voulez pas exposer vos IBOutlets avec des @property parce que vous ne voulez pas que les autres classes puissent accéder à  vos @property, et donc que vous recherchez à  ce que vos IBOutlets restent privés, bah il suffit de les déclarer la property en privé, donc de ne pas l'exposer dans le .h

    Par exemple ici pour textLabel si on ne veut pas qu'il soit accessible de l'extérieur, le .h devient :
    @interface Toto : UIViewController {<br />&nbsp; NSData* internalValue;<br />}<br />@end
    
    et le .m
    @interface Toto (/*Private*/)<br />@property(nonatomic, retain) NSString* text; // données du modèle, stocke une valeur et pas une vue<br />@property(nonatomic, retain) IBOutlet UILabel* textLabel;<br />@end<br /><br />@implementation Toto<br />@synthesize text, textLabel;<br />...<br />// mêmes implémentations de viewDidLoad, viewDidUnload et dealloc<br />@end
    
  • LexxisLexxis Membre
    20:31 modifié #34
    Je n'imaginais pas que l'on puisse le faire. Je n'imaginais tellement pas que je n'ai d'ailleurs jamais testé les property en private. Merci Ali  :D
  • 20:31 modifié #35
    Tiens donc... et Interface Builder va le voir ton textLabel?
  • zoczoc Membre
    20:31 modifié #36
    dans 1298405944:

    Tiens donc... et Interface Builder va le voir ton textLabel?

    Je me posais justement la même question, étant donné qu'à  priori Interface Builder ne va parser que les .h pour découvrir les outlets...

  • AliGatorAliGator Membre, Modérateur
    20:31 modifié #37
    Ah oui tiens non pour ce cas là  en effet y'a des chances que non (en fait j'ai posté le code direct en le tapant dans PommeDev mais j'ai même pas testé)

    Dans ce cas là  ça me parait acceptable alors de mettre une ivar avec IBOutlet dessus dans le .h, et donc de mettre le @property dans le .h pour qu'il reste privé.
    Comme IB utilise le KVC pour affecter les IBOutlets même si les méthodes ne sont pas exposées dans le .h du moment que ta classe "respondsToSelector:" sur le setter, c'est bon je pense. A valider mais bon.
  • AliGatorAliGator Membre, Modérateur
    20:31 modifié #38
    dans 1298401094:

    Je n'imaginais pas que l'on puisse le faire. Je n'imaginais tellement pas que je n'ai d'ailleurs jamais testé les property en private. Merci Ali  :D
    Les @property dans uen certaine mesure ne sont que la déclaration d'un setter et d'un getter en une ligne (bon sauf que ça apporte un peu plus, comme permet d'indiquer la politique de gestion de mémoire de cette propriété, permet de générer la backend variable automatiquement depuis le Modern Runtime, etc, mais bon).
    Donc tu peux les déclarer en private exactement comme tu déclarerais en private d'autres méthodes.

    Si tu ne connaissais pas du tout cette possibilité de déclarer des méthodes dans ton .m pour les rendre privées, cela s'appelle des "Extensions" de classe, c'est une notion voisine de la notion de "Catégorie" du langage Objective-C, sauf que ce sont des catégories un peu spéciales puisqu'elles ne doivent pas avoir de nom entre les parenthèses, et dans ce cas le compilateur va vérifier qu'elles sont bien implémentées (contrairement au cas des catégories)

    Toute la doc sur cette possibilité ici
  • LexxisLexxis Membre
    février 2011 modifié #39
    Effectivement, jusqu'à  maintenant j'utilisais les catégories pour mes fonctions privées. Voila qui va grandement m'être utile.

    J'ai effectués quelques tests concernant les outlet et avec les @property en privés. IB ne les vois pas mais aucun problème pour le compilateur. Donc il est possible de les assignés manuellement. En déclarant le mot clé IBOutlet sur la variables (sans oublier le @property) IB voit bien l'outlet... ce qui paraà®t normal !!!

    J'ai aussi créé un second fichier header contenant mes déclarations privées... et dans ce cas IB m'affiche bien mon Outlet. J'utilise Xcode 4.


    J'adore ce métier, chaque jour son lots de nouvelles connaissances !!!
  • FloFlo Membre
    20:31 modifié #40
    J'ai le code suivant :

    (.h)
    <br />@interface ITColoredViewController : NSViewController {}<br /><br />#pragma mark -<br />#pragma mark properties<br /><br />@property(nonatomic, readonly, retain) NSColor *fillColor;<br /><br />@end<br />
    


    (.m)
    <br />@interface ITColoredViewController ()<br /><br />@property(nonatomic, readwrite, retain) NSColor *fillColor;<br /><br />@end<br /><br />@implementation ITColoredViewController<br /><br />@synthesize fillColor;<br /><br />@end<br />
    


    Le problème est le suivant : si j'ai une sous-classe de ITColoredViewController, seule la property du .h est visible et donc les sous-classes n'ont qu'un accès readonly dans leur .m.

    Comment rendre la property déclarée dans le .m protected et non private tout en gardant une visibilité readonly pour les classes appelantes ?

    Merci  :D
  • AliGatorAliGator Membre, Modérateur
    20:31 modifié #41
    Malheureusement en Objective-C tu n'as pas de solution toute prête. Tu peux indiquer des modifieurs d'accessibilité pour les ivars (@public, @protected, @private) mais pas pour les méthodes (j'ai parfois trouvé ça dommage, même s'il faut avouer que ça ne m'a jamais vraiment posé problème)

    La solution qui est choisie en général pour ce genre de problème, c'est de déclarer tes propriétés privées dans un "ITColoredViewController+Private.h" et de #import ce .h dans chaque .m de tes sous-classes dans lesquelles tu en as besoin.
  • FloFlo Membre
    20:31 modifié #42
    Ok merci, je vais me débrouiller autrement dans ce cas  :)
Connectez-vous ou Inscrivez-vous pour répondre.