comparaison d'objets
Dj T@l
Membre
Bonjours tout le monde,
Alors j'ai quelque petite question avous poser:
- Comment comparer 2 objets par exemple j'ai une classe category et je veut tester si 2 instances de cette classe, quelle methode utiliser? Doit je implementer la methode : - (BOOL)isEqualTo:(id)object ou y a t'il une autre solution.
- Comment copier un objet : meme exemple avec ma classe category, j'ai une instance de cette classe et je veut la copier, je doit implementer la methode -(id)copy c'est bien ca ou je me trompe?.
Voila j'espere que j'ai été clair (pas sur).
Merci d'avance a vous
Alors j'ai quelque petite question avous poser:
- Comment comparer 2 objets par exemple j'ai une classe category et je veut tester si 2 instances de cette classe, quelle methode utiliser? Doit je implementer la methode : - (BOOL)isEqualTo:(id)object ou y a t'il une autre solution.
- Comment copier un objet : meme exemple avec ma classe category, j'ai une instance de cette classe et je veut la copier, je doit implementer la methode -(id)copy c'est bien ca ou je me trompe?.
Voila j'espere que j'ai été clair (pas sur).
Merci d'avance a vous
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Pour comparer deux objets, tu peux effectivement utiliser isEqual :
[tt]
if ([objet1 isEqualTo:objet2]==YES)
{
NSLog(@Objet1=Objet2);
}
[/tt]
Tu peux aussi comparer simplement leurs pointeurs ainsi :
[tt]
if (objet1==objet2)
{
NSLog(@Objet1=Objet2);
}
[/tt]
Pour la copie, il faut que ta classe supporte le protocole NSCopying, et tu peux ensuite utiliser copy :
[tt]
id objet2=[objet1 copy];
[/tt]
- (id)copy {
return (BMCategory alloc] init:[self name]:[self color);
}
sachant que ma classe est comme ca :
@interface BMCategory : NSObject {
NSString *name;
NSColor *color;
}
Attention, quand je voie ça sans que ce soit nuancé, je hurle. Fondamentalement, les deux sont très différents:
- isEqual envoie -hash (fouf ...couché!) aux 2 objets, cette méthode renvoie un nombre estimé suivant les variables d'instance et si ce nombre est égal pour les deux objets, alors il renvoie YES. Pour un NSNumber, le hash serait par exemple ce nombre.
-la comparaison de pointeur renvoie YES si les objets pointent vers la même adresse mémoire.
Ainsi pour:
[tt]NSString* str1 = [NSString stringWithString:@test];
NSString* str2 = [NSString stringWithString:@test];[/tt]
[str1 isEqual:str2] revoie YES;
str1 == str2 renvoie NO;
Par contre pour ta copie ton code est mauvais. Si ta classe est immutable, tu peux contenter de renvoyer [self retain]; dans le cas contraire, ce serait plutôt un truc dans le genre:
[tt]-(id)copy {
  id obj = BMCategory alloc] init];<br />//Si name est immutable:<br />  [obj setName:name]; //tu as qd même accès à la variable name à l'intérieur de la classe...<br />//Sinon<br />  [obj setName:[[name copy] autorelease;
  [obj setColor:color];
  return obj;
}[/tt]
Alors pourquoi cette distinction immutable et mutable, simplement parce que si name est mutable, le name du nouvel objet sera le même que celui de l'ancien (au sens ==), une modification qui sera faite d'un côté sera donc reportée de l'autre. Par contre si l'objet est immutable, le changement de valeur en créant un nouvel objet et en redéfinissant le pointeur. Chaque instance a son propre pointeur, donc changer l'un n'affecte pas l'autre.
Hurles pas trop fort Renaud, il est tard quand même... :P
En tout cas, merci pour cette précision importante.
Dans ce cas la, on dit:
Par contre dans le cas que je donne :
(id)copy {
return (BMCategory alloc] init:[self name]:[self color);
}
[self name] et [self color] ne sont pas des variables mais des methodes (mes accesseur) et il renvoie deja :['variable' copy] autorelease].
Va falloir que je teste ca ce soir moi. Voir cette histoire de mutable/ immutable (mes objet doivent etre mutable en tout cas).
En tout cas merci
Par contre renvoyer [[variable copy] autorelease]; n'est pas malin (mais ce n'est pas faux) pour les objets immutables, car 1. copy ne fait jamais que renvoyer [self retain] et 2. il vaut mieux prendre l'habitude d'éviter d'utiliser l'autorelease pool (il y a des cas où ce n'est pas possible de faire autrement, comme dans le cas de renvoi d'objets mutables), nettement plus gourmande en processeur et mémoire (là tu peux l'éviter en renvoyant simplement la valeur).
Par contre (oui je sait ca fait beaucoup de question)
Ma classe category, je doit pouvoir la modifier n'importe quand donc elle est mutable si j'ai bien compris c'est ca ?
ca c'st bon
@interface BMCategory : NSObject {
NSString *name;
NSColor *color;
}
je dois pas remplacer ma NSString par une NSMutableString meme si category est mutable ?
Apres je transaform mes accesseur un
[variable copy] au lieu de [[variable] copy autorelease]
de cette maniere est ce que ma methode copy donner auparabvant reste toujours correct.Je precise que mes objets doivent etre independant si je modifie le nom ou la couleur de l'un je veut pas que cela modifier les attribut de l'autre.
Merci pour tous les conseils (pas toujours evident la gestion memoire en Objective-C)
Plus de 7 heures après c'est plus Grilled mais Carbonised Fouf
- (NSString *)name
{
  return [[name retain] autorelease];
}
J'espere que c'est bon aussi et que du coup ma methode copy est toujours valable ?
Encore une question
Quel est la difference entre
NSString* str1 = [NSString stringWithString:@test];
et
NSString* str1 = @test
je comprend pas tres bien la et quelle forme faut il utiliser ?
Pourquoi ne pas écrire simplement
La première forme crée un objet temporaire qui sera détruit quand l'autorelease pool se videra.
+
Chacha
Mias si c'est le plus ismple et que ca ne crée pas de fuite de memoire je vai fare comme c'est plus rapide a ecrire.
cate = [cat copy];
STAssertTrue([cat isEqualTo:cate], @cat & cat should be equal on color and name);
STAssertTrue([cat isEqual:cate], @cat & cat should be equal on color and name);
STAssertFalse([cat isEqual:cate], @cat & cat should be equal on color and name);
STAssertEqualObjects(cat, cate, @object shoudl be the same);
[cat release];
[cate release];
}
Sa me dit qu'il y a des erreur lors e l'execution des tes sur 2 lignes:
/Users/garcera/developement/en cours/Phoenix project/bankmanager/trunk/src/TBMCategory.m:54: error: -[TBMCategory testCopy] : "[cat isEqual:cate]" should be true. cat & cat should be equal on color and name
/Users/garcera/developement/en cours/Phoenix project/bankmanager/trunk/src/TBMCategory.m:56: error: -[TBMCategory testCopy] : '<BMCategory: 0x371b50>' should be equal to '<BMCategory: 0x371bb0>' object shoudl be the same
mais je comprend pas pourquoi en gros les objets ne sont pas egaux alors que leur varible oui. Je comprend plus rien.
Si quelqu'un a une solution ?
"[[variable retain] autorelease]", ça ne sert absolument à rien. La bonne méthode, c'est "return variable;"
Par contre, après, il faut faire attention à ce que l'on veut.
Souvent, on ne veut pas que l'utilisateur de l'accesseur puisse modifier l'objet. Donc il faut faire attention.
1) Si la variable est immutable (style NSDictionary, NSString, NSArray, NSNumber...) aucun souci
2) Si la variable est mutable (style NSMutableString, NSMutableArray...), alors il suffit de donner au type de retour de l'accesseur celui de la classe mère non mutable ! exemple:
Il y a un risque toutefois : rien n'empêche l'utilisateur avisé de passer outre cette astuce et d'envoyer malgré tout des messages de la classe mutable à l'objet non mutable : ça marchera !
3)Pour ne prendre aucun risque:
-(NSString*) name
{
 return [[name mutableCopy] autorelease];
}
Mais c'est bien lourdingue et inutile la plupart du temps
+
Chacha
J'ai plus qu'a modifié tous mes accesseur (heuresemnt que jai pas fini toute mes classes).
Bon b'eh maintenant j'ai plus qu'a finir mes test unitaire des classe de base de mon appli (je vous la presenterai des qu'elle sera plus avancé).
C'est le moment rêvé de se mettre à accessorizer !
Cf http://www.objective-cocoa.org/forum/index.php?topic=850.0
Donc je voulai verifié si c'etait bon.
Donc je pense que je vait laissé tel quel pour le moment est si je voit que c'est trop lourd en ressource je me pencherai en detail dessus.
En tout cas accessorizer est vraiment super il genere pas mal de chose, moi j'aime beaucoup surtout pour toutes les methodes repetitives.
En pus je usi pas un pros de l'objective-C donc je me renseigne en meme temps sur les bon reflexe pour evitre les probleme de memoire.
En tout cas c'est un tres bon soft qui rend de fire service. Merci de nous l'avoir presenter.