Quelques questions d'un débutant: à  quoi servent property, syntethise, release ?

apocaalypsoapocaalypso Membre
08:58 modifié dans API UIKit #1
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

Réponses

  • Philippe49Philippe49 Membre
    08:58 modifié #2
    Pour les properties

    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)...
  • Philippe49Philippe49 Membre
    avril 2009 modifié #3
    Pour les release

    • Chaque objet A d'une classe héritant de NSObject tient à  jour un compteur de références. En général, il commence avec un compteur retainCount=1.
    • Chaque fois qu'il reçoit un "retain" son compteur de références augmente de 1.
           [A retain] ==> retainCount de A ++
    • Chaque fois qu'il reçoit un "release" son compteur de références diminue de 1.
           [A release] ==> retainCount de A --
    • Dès qu'il reçoit un "release" et que son compteur de références vaut 1 (i.e retainCount va passer à  0), il reçoit le messsage dealloc et autorise le programme à  utiliser la mémoire qu'il occupe pour d'autres tâches. A est perdu corps et biens.
           [A release] + retainCount de A ==1  ==> [A dealloc]





  • Philippe49Philippe49 Membre
    08:58 modifié #4
    dans 1239479329:

    Bonjour,

    je suis complètement débutant sur la programmation iPhone.


    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)
  • schlumschlum Membre
    08:58 modifié #5
    dans 1239479329:

    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


    C'est de l'Objective C 2.0, tu pourras y revenir quand tu maà®triseras le 1.0  :P
  • apocaalypsoapocaalypso Membre
    08:58 modifié #6
    Merci de vos réponse, mais au niveau de la mémoire, ça signifie quoi ces incrémentations ?
  • AliGatorAliGator Membre, Modérateur
    08:58 modifié #7
    Ouh là  comme dit schlum, commence par l'Objective-C 1.0 si tu ne maà®trises pas ces notions, en particulier le mécanisme retain/release, c'est un principe très important à  maà®triser.

    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 :))
  • CéroceCéroce Membre, Modérateur
    08:58 modifié #8
    Un article qui a dix ans (!) mais qui reste une reférence sur la gestion de la mémoire en ObjC: Stepwise: Memory Management with Cocoa/WebObjects

    Le chapitre qui lui est consacré dans le livre d'Hillegass est plus accessible, mais dit à  peu près la même chose.
  • apocaalypsoapocaalypso Membre
    08:58 modifié #9
    Merci pour tous ces liens !

    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 :

    -(void)dealloc<br />{<br />&nbsp; &nbsp; &nbsp;  [super dealloc];<br />}
    


    dans toutes mes vues mais sinon rien. Je ne sais absolument pas comment faire pour libérer de la mémoire.
  • Philippe49Philippe49 Membre
    08:58 modifié #10
    dans 1239743013:

    Merci de vos réponse, mais au niveau de la mémoire, ça signifie quoi ces incrémentations ?

    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.
  • Philippe49Philippe49 Membre
    08:58 modifié #11
    dans 1239918930:

    Merci pour tous ces liens !

    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 :

    -(void)dealloc<br />{<br />&nbsp; &nbsp; &nbsp;  [super dealloc];<br />}
    


    dans toutes mes vues mais sinon rien. Je ne sais absolument pas comment faire pour libérer de la mémoire.


    Pour permettre une bonne gestion de la mémoire, il faut que
    • Lors de la durée de vie d'un objet, toutes les variables d'instances reçoivent exactement autant d'incrémentations de leur retain count que de décrémentations. Le modèle le plus simple est que cette variable soit créée ([[.. alloc] init...] ) lors d'une phase d'initialisation de l'objet (une méthode commençant par init, un viewDidLoad, un awakeFromNib, ...) et que qu'elle reçoive un release dans le dealloc.
    • Toute variable temporaire définie dans une méthode reçoivent lors de sa durée de vie autant de décrémentations que d'incrémentations. Souvent on crée ces variables en mode autorelease (ex NSString * string=[NSString stringWithFormat:@Hello World %d,2009]). Cela signifie un retain temporaire sur l'objet temporaire (ex:la NSString) et un release automatique à  la fin de la boucle d'événements dont on n'a pas besoin de se charger.
      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
  • muqaddarmuqaddar Administrateur
    08:58 modifié #12
    Je profite de ce sujet pour poser une question.

    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 :

    <br />- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {<br />	currentElement = [elementName copy];<br />	if ([elementName isEqualToString:@&quot;item&quot;]) {<br />		// clear out our story item caches...<br />		item = [[NSMutableDictionary alloc] init];<br />		currentTitle = [[NSMutableString alloc] init];<br />		currentDate = [[NSMutableString alloc] init];<br />		currentSummary = [[NSMutableString alloc] init];<br />		currentLink = [[NSMutableString alloc] init];<br />	}<br />}<br />
    


    mais fait les releases des propriétés uniquement dans le - (void)dealloc :

    - (void)dealloc {<br />	[currentElement release];<br />	[rssParser release];<br />	[stories release];<br />	[item release];<br />	[currentTitle release];<br />	[currentDate release];<br />	[currentSummary release];<br />	[currentLink release];<br /><br />	[super dealloc];<br />}
    



    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 :

    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    


    et non pas dans le dealloc !

    Sinon on aura X retain sur chaque propriété pour 1 seul release dans le dealloc !

  • AliGatorAliGator Membre, Modérateur
    08:58 modifié #13
    Tout à  fait, il faut en effet faire les release au début du didStartElement, tant pour les variables qu'il réaffecte avec un alloc/init que la variable currentElement sur laquelle il fait un copy...

    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.
    // .h<br />...<br />@property(nonatomic,copy) NSString * currentElement;<br />@property(nonatomic, retain) NSMutableDictionary *item;<br />@property(nonatomic, retain) NSString *currentTitle, *currentDate, *currentSummary, *currentLink;<br /><br />// .m<br />- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {<br />&nbsp;  self.currentElement = elementName;<br />&nbsp;  if ([elementName isEqualToString:@&quot;item&quot;]) {<br />&nbsp; &nbsp; &nbsp; // clear out our story item caches...<br />&nbsp; &nbsp; &nbsp; self.item = [NSMutableDictionary dictionary];<br />&nbsp; &nbsp; &nbsp; self.currentTitle = [NSMutableString string];<br />&nbsp; &nbsp; &nbsp; self.currentDate = [NSMutableString string];<br />&nbsp; &nbsp; &nbsp; self.currentSummary = [NSMutableString string];<br />&nbsp; &nbsp; &nbsp; self.currentLink = [NSMutableString string];<br />&nbsp;  }<br />}<br />
    
  • muqaddarmuqaddar Administrateur
    08:58 modifié #14
    dans 1239954443:

    Tout à  fait, il faut en effet faire les release au début du didStartElement, tant pour les variables qu'il réaffecte avec un alloc/init que la variable currentElement sur laquelle il fait un copy...


    En fait, moi j'aurais plutôt vu les releases dans le didEndElement et pas dans le didStartElement !

    Comme ça :

    <br />- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {<br />	if ([elementName isEqualToString:@&quot;item&quot;]) {<br />		// add values to item<br />		[item setObject:currentTitle forKey:@&quot;title&quot;];<br />		[item setObject:currentDate forKey:@&quot;date&quot;];<br />		[item setObject:currentDescription forKey:@&quot;description&quot;];<br />		[item setObject:currentLink forKey:@&quot;link&quot;];<br />		[item setObject:currentCategory forKey:@&quot;category&quot;];<br />		// store that item into the array<br />		[items addObject:[item copy]];<br />		// release ivars<br />		[currentTitle release];<br />		[currentDate release];<br />		[currentDescription release];<br />		[currentLink release];	<br />		[currentCategory release];	<br />		[item release];<br />	}<br />}<br />
    
  • AliGatorAliGator Membre, Modérateur
    08:58 modifié #15
    Ah ben oui, en effet, c'est encore mieux, t'as bien raison ;) ^^
  • muqaddarmuqaddar Administrateur
    08:58 modifié #16
    D'ailleurs, je continue sur ce tutorial trouvé. Pourquoi le développeur fait un :

    [items addObject:[item copy]];
    


    et pas :

    [items addObject:item];
    


    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.
  • AliGatorAliGator Membre, Modérateur
    08:58 modifié #17
    A la limite s'il faisait
    NSDictionary* itemCopy = [item copy];<br />[items addObject:itemCopy];<br />[itemCopy release];
    
    Au niveau gestion mémoire ça serait acceptable, même si je ne vois pas quel est l'intérêt de faire une copie plutôt que de garder l'original en ayant juste un retain dessus... mais au moins ça serait cohérent au niveau de la gestion mémoire...

    Il m'a l'air foireux au niveau gestion mémoire ton tuto...
  • muqaddarmuqaddar Administrateur
    08:58 modifié #18
    dans 1239958633:

    A la limite s'il faisait
    NSDictionary* itemCopy = [item copy];<br />[items addObject:itemCopy];<br />[itemCopy release];
    
    Au niveau gestion mémoire ça serait acceptable, même si je ne vois pas quel est l'intérêt de faire une copie plutôt que de garder l'original en ayant juste un retain dessus... mais au moins ça serait cohérent au niveau de la gestion mémoire...

    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.
  • apocaalypsoapocaalypso Membre
    avril 2009 modifié #19
    Merci pour toutes ces réponses !

    En fait mon dealloc est ceci :
    -(void)dealloc<br />{<br />	[super dealloc];<br />	[bgFiles release];<br />	[soundListLow release];<br />	[soundListMedium release];<br />	[soundListHigh release];<br />	[selectedSound release];<br />}<br />
    

    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 !

    -(void)drawRect:(CGRect)rect<br />{	<br />	CGContextRef context = UIGraphicsGetCurrentContext();<br />	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();<br />		<br />	// DRAW CIRCLE<br />	// Settings for the glow effect<br />	float glowWidth = 20.0;<br />	<br />	// Color for a blue-violet color<br />	float colorValues&#91;] = { 0.67058824, 0.51764706, 0.98431373, 1.0 };<br />	<br />	<br />	CGColorRef glowColor = CGColorCreate(colorSpace, colorValues);<br />	CGContextSetShadowWithColor(context, CGSizeMake(0.0, 0.0), glowWidth, glowColor);<br /><br />	// Fill with a clear violet-blue color<br />	CGContextSetFillColorWithColor(context, glowColor);<br />	<br />	CGContextFillEllipseInRect(context, blushBall);<br />	<br />	// DRAW CIRCLE 2	<br />	// Color for a blue-violet color	<br />	CGContextSetShadowWithColor(context, CGSizeMake(0.0, 0.0), glowWidth, glowColor);<br />	<br />	// Fill with a clear violet-blue color<br />	//CGContextSetRGBFillColor(context, 0.67058824, 0.51764706, 0.98431373, 1.0);<br />	CGContextSetFillColorWithColor(context, glowColor);<br />	<br />	CGContextFillEllipseInRect(context, blushBall2);<br />}
    


    Mais je ne voit pas de fuites.
    Et ici mes méthodes pour jouer un son et afficher un fond d'écran aléatoire :
    // Play the sound<br />-(void)playSoundCircle<br />{<br />	// Choosing a random sound<br />	NSUInteger soundIndex = arc4random() % [soundListLow count];<br />	NSString *sound = [soundListLow objectAtIndex:soundIndex];<br />	// Playing the random sound<br />	NSBundle *mainBundle = [NSBundle mainBundle];	<br />	selectedSound = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:sound ofType:EXT_SOUNDS]];<br />	// Play the sound<br />	[selectedSound play];<br />	//[selectedSound release];<br />	NSLog(@&quot;Playing sound&quot;);<br />}<br /><br />// Display a random background<br />-(void)displayBackground<br />{<br />	// We change the background image for a short time<br />	randBg = 0 + arc4random() % [bgFiles count];<br />	NSString *changeBackground = [bgFiles objectAtIndex:randBg];<br />	[self setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:changeBackground]]];<br />	NSLog(@&quot;New background&quot;);<br />}	<br />
    

    Mystère...

    Mais je vais essayer de me renseigner sur le chap. 4 de Hillegass.
  • CéroceCéroce Membre, Modérateur
    avril 2009 modifié #20
    Comme j'imagine que Core Graphics fonctionne pareil sur Mac et iPhone:

    Après
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    


    tu as forcément
    CGColorSpaceRelease(colorSpace);
    


    Et après un
    CGColorRef glowColor = CGColorCreate(colorSpace, colorValues);
    


    tu as forcément
    CGColorRelease(glowColor);
    



    Qu'Apple n'ait pas mis les classes graphiques sur l'iPhone me dépasse...
  • CéroceCéroce Membre, Modérateur
    08:58 modifié #21
    Pour l'autre partie du code: tu as le même problème avec l'image de fond et le son. Dans les deux cas, tu as une liste de NSString dans laquelle tu vas piocher le nom de l'élément puis le charger. Sauf, que tu n'a pas l'air de savoir quand retirer l'objet de la mémoire.

    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:

    <br />- (id) init<br />{<br />	if(self = [super init])<br />	{<br />		// &#39;sounds&#39; est un NSArray (variable d&#39;instance)<br />		SoundEffect sound1 = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:@&quot;sound1&quot; ofType:EXT_SOUNDS]];<br />		SoundEffect sound2 = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:@&quot;sound2&quot; ofType:EXT_SOUNDS]];<br />		SoundEffect sound3 = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:@&quot;sound3&quot; ofType:EXT_SOUNDS]];<br />		<br />		sounds = [NSArray arrayWithObjects:sound1, sound2, sound3, nil];<br />		[sound1 release];<br />		[sound2 release];<br />		[sound3 release];<br />	}<br />	<br />	return self;<br />}<br />- (void) dealloc<br />{<br />	[sounds release];<br />	<br />	[super dealloc];<br />}<br /><br />-(void)playSoundCircle<br />{<br />	// Playing a random sound<br />	NSUInteger soundIndex = arc4random() % [sounds count];<br />	SoundEffect sound = [sounds objectAtIndex:soundIndex];<br />	[sound play];<br />}<br />
    


    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.
  • apocaalypsoapocaalypso Membre
    08:58 modifié #22
    Merci !
    Oui c'est que je fais à  peu près dans mon awakeFromNib :

    // All the background images files<br />	bgFiles = [[NSArray alloc] initWithObjects:@&quot;polied-bg.png&quot;,<br />												@&quot;polied-lineCenter-bg.png&quot;,<br />												@&quot;polied-circleCenter-bg.png&quot;,<br />												@&quot;polied-musicNote-bg.png&quot;,<br />												@&quot;polied-Bangalter-bg.png&quot;,<br />												nil];<br /><br />soundListLow = [[NSArray alloc] initWithObjects:@&quot;cshd6&quot;, @&quot;handclp1&quot;, @&quot;hhod2&quot;, @&quot;ht3d3&quot;, @&quot;ride4&quot;, @&quot;stot7sa&quot;, @&quot;btaaad0&quot;,<br />					@&quot;clop1&quot;, nil];<br /><br />
    


    Mais c'est quel object et quand que je ne sais pas releasé.

    Dans mon dealloc j'ai :
    -(void)dealloc<br />{<br />&nbsp; &nbsp; &nbsp;  [super dealloc];<br />&nbsp; &nbsp; &nbsp;  [soundListLow release];<br />&nbsp; &nbsp; &nbsp;  [bgFiles release];<br />}
    
  • Philippe49Philippe49 Membre
    avril 2009 modifié #23
    Une remarque sur la définitiion de la couleur:
    <br />	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();<br />	<br />	// Color for a blue-violet color<br />	float colorValues&#91;] = { 0.67058824, 0.51764706, 0.98431373, 1.0 };<br /><br />	CGColorRef glowColor = CGColorCreate(colorSpace, colorValues);
    


    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
  • Philippe49Philippe49 Membre
    avril 2009 modifié #24
    Une remarque sur le dealloc : il ne m'est jamais venu à  l'esprit de supprimer le contenant avant de supprimer le contenu ==> Le [super dealloc] se met en fin de la méthode dealloc.

    -(void)dealloc
    {
           [super dealloc];
           [soundListLow release];
           [bgFiles release];
           [super dealloc];
    }
  • Philippe49Philippe49 Membre
    avril 2009 modifié #25
    Je ne vois pas trop quel est ton code maintenant mais ce qui est sur c'est que le code ci-dessous provoque une grave fuite mémoire.
    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)

    <br />....<br />	NSBundle *mainBundle = [NSBundle mainBundle];	<br />	selectedSound = [[SoundEffect alloc] initWithContentsOfFile:[mainBundle pathForResource:sound ofType:EXT_SOUNDS]];<br />	// Play the sound<br />	[selectedSound play];<br />	//[selectedSound release];<br />	NSLog(@&quot;Playing sound&quot;);<br />....<br />
    



    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

  • apocaalypsoapocaalypso Membre
    avril 2009 modifié #26
    dans 1240008396:

    Une remarque sur la définitiion de la couleur:
    <br />	CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();<br />	<br />	// Color for a blue-violet color<br />	float colorValues&#91;] = { 0.67058824, 0.51764706, 0.98431373, 1.0 };<br /><br />	CGColorRef glowColor = CGColorCreate(colorSpace, colorValues);
    


    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


    Merci, j'ai bien fais ce que tu m'as conseillé sur le release.

    Mais pour le drawRect: j'utilise :
    CGContextSetShadowWithColor(context, CGSizeMake(0.0, 0.0), glowWidth, glowColor);<br /><br />	// Fill with a clear violet-blue color<br />	CGContextSetFillColorWithColor(context, glowColor);<br />        CGContextFillEllipseInRect(context, blushBall);<br />
    

    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.
  • AliGatorAliGator Membre, Modérateur
    08:58 modifié #27
    dans 1240067882:
    Mais pour le drawRect: j'utilise :
    CGContextSetShadowWithColor(context, CGSizeMake(0.0, 0.0), glowWidth, glowColor);<br /><br />	// Fill with a clear violet-blue color<br />	CGContextSetFillColorWithColor(context, glowColor);<br />&nbsp; &nbsp; &nbsp; &nbsp; CGContextFillEllipseInRect(context, blushBall);<br />
    

    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 !
    Je ne vois pas dans ces fonctions où tu as besoin d'un ColorSpace ?!
    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.

    CGColorRef glowColor = [UIColor colorWithRed:0.67f green:0.518f blue:0.98f alpha:1.0f].CGColor;
    
    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.
  • apocaalypsoapocaalypso Membre
    08:58 modifié #28
    Merci Ali.
    Lorsque je supprime tous les CGContextSetShadowWithColor(), il n'y a presque plus aucun lag.
Connectez-vous ou Inscrivez-vous pour répondre.