Les scripts de XCode
Philippe49
Membre
XCode possède un menu script bien utile !
Visitez-le ...
Le choix fait pour le code des accessor-methods est intéressant
Par exemple pour une variable NSString * destination, le script fournit l'implémentation suivante :
- (void)setDestination:(NSString *)value {
if (destination != value) {
[destination release];
destination = [value copy];
}
}
L'idée de la copie dans le set.. est différente de celle habituellement présentée dans la littérature traditionnelle : destination=[value retain]; .
Elle entraà®ne que les changements ultérieurs dans value ne seront pas reportés dans destination. Cela pose égalemet le problème de savoir si on fait de la copie profonde ou superficielle.
-(NSString *)destination {
return [[destination retain] autorelease];
}
Plus anodin, mais moi, bêtement et jusqu'à maintenant, je mettais return destination;. Cela semble prendre plus de précaution, mais pourquoi ? Dans des applications multi-thread où destination serait détruite sournoisement ... ?
Pour une variable int tag, on voit ce code
- (void)setTag:(int)value {
if (tag != value) {
tag = value;
}
}
et là , je ne vois pas à quoi sert le test.
Visitez-le ...
Le choix fait pour le code des accessor-methods est intéressant
Par exemple pour une variable NSString * destination, le script fournit l'implémentation suivante :
- (void)setDestination:(NSString *)value {
if (destination != value) {
[destination release];
destination = [value copy];
}
}
L'idée de la copie dans le set.. est différente de celle habituellement présentée dans la littérature traditionnelle : destination=[value retain]; .
Elle entraà®ne que les changements ultérieurs dans value ne seront pas reportés dans destination. Cela pose égalemet le problème de savoir si on fait de la copie profonde ou superficielle.
-(NSString *)destination {
return [[destination retain] autorelease];
}
Plus anodin, mais moi, bêtement et jusqu'à maintenant, je mettais return destination;. Cela semble prendre plus de précaution, mais pourquoi ? Dans des applications multi-thread où destination serait détruite sournoisement ... ?
Pour une variable int tag, on voit ce code
- (void)setTag:(int)value {
if (tag != value) {
tag = value;
}
}
et là , je ne vois pas à quoi sert le test.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
La copie c'est pas très optimisée en tout cas, et ça bouffe de la mémoire pour rien (en général)
Quand on a besoin d'une copie, on la fait au dessus du "set" dans la philosophie Obj-C
destination -> voui, pourquoi pas... Ca empêche effectivement la destruction de l'objet par un autre thread
setTag -> Question d'optimisation je pense... Un test est beaucoup plus rapide qu'une affectation.
bof... également, mais ce choix de script me questionne.
Cela peut peut-être se comprendre si on prend comme mode de programmation de créer l'objet en autorelease (genre stringWith...) dans la méthode appelante.
Peut-être, mais il est sans doute assez rare de remplacer une variable par son identique !
D'autant plus après avoir lu la doc sur la méthode copy
[size=14pt]copy[/size]
Returns the object returned by copyWithZone:, where the zone is nil.
...
NSObject does not itself support the NSCopying protocol. Subclasses must support the protocol and implement the copyWithZone: method.
Cela répond en même temps au problème de savoir si la copie effectue elle-même des copies des objets pointés dans la liste des variables, ou si elle se contente de copier les références. (copie profonde/superficielle)
rebof ...
Une copie de NSArray par exemple ne recopie pas tous les objets qu'il contient.
Il est assez rare de trouver une copie en Objective-C.
Ex : quand on fait un "addObject" sur un NSMutableArray, il se contente d'incrémenter le compteur de référence de l'objet.
Foundation ne fonctionne qu'en copie superficielle, pour faire de la "deep copy", plus de détails ici.
Sinon d'expérience, les tests d'adresses sont surtout intéressants lorsqu'il y a du refresh d'interface graphique derrière (ex: rafraà®chir un libellé très souvent).
Oui... "copy" sur un objet immuable se contente de faire un "retain".
Ce que j'avais cru comprendre à la lecture de cette doc, c'est qu'Objective-C laissait (courageusement) au programmeur le choix de sa méthode copy : deep copy ou shallow copy ou autre.
Et que, dès lors, l'utilisation de copy dans les accessor-methods était à vérifier scrupuleusement.
Cela me semble assez logique dans le fond. Si on prend pour exemple NSData, même si ce n'est pas un objet mutable, cela n'empêche pas qu'on peut accéder et modifier le contenu du buffer via "getBytes". Donc en toute logique, dans ce cas précis, le développeur qui a codé cette classe a implémenté une copie complète. En extrapolant au classes de monsieur tout le monde, je vois mal comment Apple pourrait imposer une règle entre "deep copy" ou "shallow copy".
Qu'en pensez-vous?
Cependant, en C++ il y a un constructeur de recopie par défaut qui fait une copie bit à bit ; un copy de NSObject pourrait faire ça... (Mais ce n'est pas vraiment la philosophie de l'Objective-C qui laisse le choix au programmeur de l'implémentation de tel protocole pour tel objet).
Pour "getBytes" par contre, je ne suis pas d'accord... Ca copie les données du NSData dans un autre buffer
Et "cStringUsingEncoding" sur NSString par exemple, renvoie un "const char *" ce qui spécifie qu'il ne faut pas y toucher.
Ceci dit, si vous voulez rajouter vos propres scripts, le menu de XCode les prend dans le répertoire :
/Library/Application\ Support/Apple/Developer\ Tools/Scripts/
C'est ce que je voulais dire quand je parlais d'une copie complète (je pensais au buffer). Je me suis sans doute mal exprimé.
Ah... J'ai cru que tu disais qu'on pouvait modifier un objet NSData via getBytes
La tournée est pour moi!