# Tutoriel: "Création d'un colorimètre avec cocoa"



## Old Salt (12 Mars 2005)

Bonjour à tous,
J'ai commencé les tutoriels il y a quelques semaines, en suivant à la lettre les instructions.
En les reprenant tranquillement, je m'aperçois que je ne suis pas certain de comprendre certains points.
Par exemple, lors de la création du Colorimètre, on implémente la méthode "updateColor":

- (void)updateColor
{
NSColor  *aColor = [NSColor colorWithCalibratedRed:redValue green:greenValue blue:blueValue alpha:alphaValue];
[colorWell setColor:aColor];
}

1/ Pourquoi n'est-il pas nécessaire de faire un [[NSColor alloc] init] ?
2/ Est-ce parce que la méthode "+ colorWithCalibratedRed:redValue green:greenValue...." est du type "+" ?
3/ Les méthodes "+" sont-elles toujours toutes des "constructeurs de commodité" ?
4/ Si l'on utilise une méthode "-" au lieu d'une méthode "+", est-on toujours obligé de faire un "alloc / init" (et un release ou autorelease) ?

Si vous pouviez me préciser ces points, je crois que je ferais un pas dans la bonne direction   
Merci.


----------



## mpergand (12 Mars 2005)

Salut   

Tu abordes deux notions essentielles de la programmation objets:
 - les contructeurs
 - les méthodes de classe(+) et les méthodes d'instance(-)

En C++ ou Java, pour créer un objet on emploie l'opérateur new, suivi du nom de la classe de l'objet, ex:

NSColor color= new NSColor();    // java

En ObjectiveC ça se complique, car il n'y a pas de vrai contructeurs, ce sont des méthodes  débutant par init, ex:
 initWithString
 initWithFloat

et si tu regardes bien ce sont des méthodes d'instance, donc tu es obligé d'appeler alloc, qui elle est une méthode de classe (ouf sauvé):
 NSColor* color=[[NSColor alloc] init];

Effectivement, il existe des constructeurs de commodité(+), qui eux créent directement l'objet voulu:
NSColor* color=[NSColor colorWithCalibratedRed:...];

Pour le  gestion mémoire de ces objets, il convient d'appliquer la règle qui suit:
- dans le cas d'un [[alloc] init] , on considère que tu es le créateur (methode alloc) de cette objet et en conséquence responsable de sa destruction, donc c'est à toi de faire un release quand tu n'as plus besoin de cet objet.
- dans l'autre cas, tu n'es pas créateur de cet objet et donc pas responsable de sa destruction, c'est pour ça qu'il est en autorelease. Ne pas oublier, bien sûr, de faire un retain, si tu veux utiliser cet objet ailleurs dans ton appli.


----------



## Old Salt (12 Mars 2005)

Salut,
Le monde est petit, n'est-ce pas ?   
Merci pour ces précisions.
Un dernier (provisoirement) point:

"- dans l'autre cas, tu n'es pas créateur de cet objet et donc pas responsable de sa destruction, c'est pour ça qu'il est en autorelease. Ne pas oublier, bien sûr, de faire un retain, si tu veux utiliser cet objet ailleurs dans ton appli."

OK, j''ai bien compris le coup du "retain".
Si je veux utiliser cet objet ailleurs (donc dans une autre méthode de mon appli), il faut que je le déclare dans le fichier "header" (avec "NSColor *aColor") et je fais le reste de l'initialisation dans une de mes méthodes, c'est bien ça ?  :rose:


----------



## mpergand (12 Mars 2005)

> Si je veux utiliser cet objet ailleurs (donc dans une autre méthode de mon appli), il faut que je le déclare dans le fichier "header" (avec "NSColor *aColor") et je fais le reste de l'initialisation dans une de mes méthodes, c'est bien ça



Tout à fait. 

Par esprit de clareté, je n'ai pas parlé de NSRunloop, NSAutoreleasePool, etc
Pour tout savoir, tu peux lire Cette Page


----------



## Old Salt (13 Mars 2005)

Encore merci *mpergand*  (je digère tranquillement "object ownership and disposal").
J'avais bien compris les 2 façons de créer un objet (soit par alloc / init, soit par constructeur de commodité) et pensais que tout était dit, mais il semble y avoir une troisième façon: avec Interface Builder !!!
En effet, si un objet a été créé dans IB, il n'est jamais créé par le code (du moins dans les tutoriels que j'ai fait); alors est-ce réellement une 3ème méthode ou bien est-elle assimilée à une des deux autres ?
Et quelle est la durée de vie de l'objet créé dans IB ? Tant que le fichier NIB correspondant est chargé en mémoire ?


----------



## mpergand (13 Mars 2005)

Tu n'as pas à te soucier des objets créés dans IB, c'est le rôle du WindowController


----------



## arnolix (14 Mars 2005)

Ok avec tout ce qui a été dit.
Mais cependant il y a un problème spécifique à NSColor (et à d'autres) lorsqu'il s'agit de retenir suite à un constructeur de commodité (et qui n'est quasiment pas mentionné dans les diverses docs). J'avais déjà posté à l'époque à ce sujet car ça m'avait cassé un peu la tête.
Même Apple donne des exemples foireux la-dessus (on trouve :     color = [[NSColor redColor] retain]; dans l'exemple DotView ).

Un objet comme [NSColor redColor] ne se retient pas. Y a qu'à faire : [[NSColor redColor] retainCount], pour constater qu'il retourne -1 !

Si je ne me trompe pas (à confirmer) ce sont des objets partagés (sharedObject).

Mais là où ca se corse c'est que si tu fais :

NSColor *aColor = [NSColor colorWithCalibratedRed:1 green:0 blue:0 alpha:0];

et bien ton aColor est en fait un [NSColor redColor] ! et si tu le retiens pour ensuite le relacher, t'as un plantage car tu fais un release sur un retaincount qui vaut -1.

En résumé, si tu fais un :
NSColor *aColor = [NSColor colorWithCalibratedRed:redValue green:greenValue blue:blueValue alpha:alphaValue];
il n'est pas dit que tu puisses le retenir.

@+


----------



## Old Salt (14 Mars 2005)

Bien, merci, euhhh, il faudra que je m'en souvienne  :mouais:


----------

