Quelques questions d'un débutant: à quoi servent property, syntethise, release ?
apocaalypso
Membre
Bonjour,
je suis complètement débutant sur la programmation iPhone. Je voudrais juste savoir à quoi servent concrètement @property, @synthetise et les release dans le dealloc ?
Merci d'avance !
Guillaume
je suis complètement débutant sur la programmation iPhone. Je voudrais juste savoir à quoi servent concrètement @property, @synthetise et les release dans le dealloc ?
Merci d'avance !
Guillaume
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
1) Cela permet de ne pas écrire tout le code des accesseurs
@property (nonatomic,retain) NSString * name;
@synthesize name;
te code proprement les accesseurs (compatibles KVO,KVC)
-(NSString*) name;
-(void) setName:(NSString *) aNewName;
Et cela est encore plus complet pour des accesseurs pour des collections NSArray, NSSet, NSDictionary, ..
2) Cela permet une lecture significative de ton fichier d'interface, en listant des properties ...
3)...
   [A retain] ==> retainCount de A ++
   [A release] ==> retainCount de A --
   [A release] + retainCount de A ==1 ==> [A dealloc]
Mais là , [url=http://comme le répète à juste titre Schlum]comme le dit à juste titre Schlum[/url], je crois que tu devrais passer par la case étude d'Objective-C pour obtenir un certain nombre de principes, que tu n'acquièreras pas seulement par la pratique.
(le livre de Hillegass est un vrai régal)
C'est de l'Objective C 2.0, tu pourras y revenir quand tu maà®triseras le 1.0 :P
Et surtout n'hésite pas à lire la doc Apple, y'a pas que les docs de la Reference Library, y'a aussi plein d'articles complets d'Apple pour expliquer les concepts.
En particulier la lecture de cet article sur la gestion mémoire te fera le plus grand bien...
(à croire que les gens ne savent pas que la doc existe, pourtant celle d'Apple est plutôt bien foutue et bien fournie... d'ailleurs ce lien en particulier je vais finir par le mettre dans ma signature )
Le chapitre qui lui est consacré dans le livre d'Hillegass est plus accessible, mais dit à peu près la même chose.
Parce qu'en fait je suis un peu affolé. Quand je teste sur l'iPhone c'est assez lent. Mais le problème c'est que je n'ai aucune notion sur le release, j'ai juste :
dans toutes mes vues mais sinon rien. Je ne sais absolument pas comment faire pour libérer de la mémoire.
Techniquement, cela ne change pas l'empreinte mémoire, il y a toujours autant d'octets occupés. Un retain count élevé n'a aucune influence sur la rapidité d'exécution de ton programme.
Pour permettre une bonne gestion de la mémoire, il faut que
On peut naturellement ne pas utiliser ce mode autorelease et faire soi-même le retain et le release sur cette variable temporaire.
Exemple:
Voir le ch 4 de Hillegass
Dans ce tutorial de parsing RSS :
http://theappleblog.com/2008/08/04/tutorial-build-a-simple-rss-reader-for-iphone/
le développeur instancie les propriétés dans cette méthode :
mais fait les releases des propriétés uniquement dans le - (void)dealloc :
Or, la première méthode citée est appelée à chaque item RSS... donc X fois.
Il me paraà®t donc juste de faire le release des propriétés dans :
et non pas dans le dealloc !
Sinon on aura X retain sur chaque propriété pour 1 seul release dans le dealloc !
Sinon une autre solution est de passer par les @property(retain) pour toutes celles qu'il alloc/init dans ton if, et @property(copy) pour currentElement... de synthétiser ces @properties ensuite pour générer les accesseurs correspondants automatiquement... et d'utiliser une affectation simple pour self.currentElement (le setter faisant tout seul la copie) et une affectation d'objet autorelease pour les autres. Faut juste alors ne pas oublier le "self." devant, pour que ça appelle bien le setter via la notation pointée des properties.
En fait, moi j'aurais plutôt vu les releases dans le didEndElement et pas dans le didStartElement !
Comme ça :
et pas :
qui marche très bien !
Il me semble qu'en faisant un "copy", il fait un retain de plus qui n'est pas nécessaire.
Il m'a l'air foireux au niveau gestion mémoire ton tuto...
Oui c'est bien ce que je me suis dit !
Mais en tant que "revenant", je me posais ces questions qui me faisaient douter.
En fait mon dealloc est ceci :
où tous sont des NSArray sauf selectedSound qui est de la classe SoundEffect permettant de jouer un son.
Mais il me semble que mes fuites de mémoires viennent de mon drawRect car lorsque je diminue le nombre de cercles 2 ou 1 les lags se font beaucoup moins ressentir !
Mais je ne voit pas de fuites.
Et ici mes méthodes pour jouer un son et afficher un fond d'écran aléatoire :
Mystère...
Mais je vais essayer de me renseigner sur le chap. 4 de Hillegass.
Après
tu as forcément
Et après un
tu as forcément
Qu'Apple n'ait pas mis les classes graphiques sur l'iPhone me dépasse...
Tu as deux solutions:
1- Tu charges le son à chaque fois que tu le joues, puis tu le relâches de suite, mais je ne suis pas sûr que ça marche, puisque si tu le vires, il s'arrête certainement de jouer (d'où le code en commentaire).
2-Mieux: tu charges tous les sons au début du programme:
La méthode init est celle de ta vue (je ne sais pas comment s'appelle cette méthode sur l'iPhone). D'ailleurs, il faudra que tu sépares ce code de celui de la vue; ce n'est pas très "MVC".
L'inconvénient de cette approche, c'est que toutes les ressources restent en mémoire tout le temps.
Oui c'est que je fais à peu près dans mon awakeFromNib :
Mais c'est quel object et quand que je ne sais pas releasé.
Dans mon dealloc j'ai :
Pourquoi ne pas utiliser la méthode
UIColor * color=[UIColor colorWithRed: green: blue: alpha: ];
Cela évite du code et le CGColorSpaceRelease, CGColorRelease, qu'il faudrait rajouter à ton code (cf Céroce)
et si tu as besoin de la version CGColorRef, tu peux toujours te rabattre sur la property color.CGColor
-(void)dealloc
{
   [super dealloc];
   [soundListLow release];
   [bgFiles release];
   [super dealloc];
}
En effet chaque fois que la méthode est appelée une nouvelle instance de SoundEffect est créée avec un retain count de 1, et cette instance ne reçoit jamais de release puisque la référence est perdue lors de l'appel suivant de la méthode (selectedSound pointe vers une autre instance)
Pour éviter de créer tous les sons dès le début ce qui est gourmand en mémoire, il suffit de mettre un
[selectedSound release]
avant de récréer une instance :
selectedSound = SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:sound ofType:EXT_SOUNDS;
tout en gardant le [selectedSOund release] dans le dealloc
Merci, j'ai bien fais ce que tu m'as conseillé sur le release.
Mais pour le drawRect: j'utilise :
et ces fonctions nécessitent le colorSpace et colorRef, alors je ne sais pas trop comment ajouter cet effet de glow sans celles-ci, je n'ai pas trouvé de fonctions similaires dans la Doc.
En tout cas merci !
EDIT: J'ai bien l'impression que c'est CGContextSetShadowWithColor() qui provoque le lag.
Par contre en effet tu as besoin de CGColorRef... mais comme l'a dit Philippe49, tu peux créer une UIColor et lui demander sa CGColorRef équivalente, plutôt que de créer la CGColorRef toi-même avec les méthode de CoreGraphics. Ces 2 méthodes se valent, mais l'intérêt de passer par UIColor c'est que c'est un NSObject Cocoa pour lequel on peut gérer la mémoire comme habituellement, avec alloc/init/release (ou autorelease). Bon tu vas me dire, entre faire un CGColorRelease ou un [maUIColor release], y'a pas grande différence en même temps, mais bon, c'est plus facile pour ceux qui sont habitués à manipuler les NSObjects Cocoa que les fonctions C de CoreGraphics.
Là comme la UIColor créée par "colorWithRed:green:blue:alpha:" est autorelease, tu n'as pas à gérer sa mémoire. Et tu n'as pas non plus donc à gérer la mémoire du glowColor, qui est une propriété de cet objet UIColor, et sera donc détruite/releasée en même temps que ledit objet UIColor.
Lorsque je supprime tous les CGContextSetShadowWithColor(), il n'y a presque plus aucun lag.