2009-09-16 4 views
1

Cette méthode est générée par Xcode 3.2 en utilisant « accesseurs defs au presse-papiers »Est-ce que c'est nécessaire?

- (void)setBodyMass:(int)newBodyMass { 
    if (bodyMass != newBodyMass) { 
     bodyMass = newBodyMass; 
    } 
} 

ce que je pourrais écrire tout aussi facilement ce que vous voyez ci-dessous? Il semble faire un test conditionnel pour l'enregistrer en faisant une affectation redondante possible.

- (void)setBodyMass:(int)newBodyMass { 
     bodyMass = newBodyMass; 
} 

acclamations -Gary-

+0

Eh bien, si c'est déjà la même valeur, je ne vois pas pourquoi vous devriez le réinitialiser. – Garrett

+0

IIRC, ceci est juste un guide de style.Cela vous évite d'oublier accidentellement d'appeler [release bodyMass] avant l'affectation. – Seth

+0

Je peux voir pourquoi pour un objet (comme un NSString) parce que si vous ne testez pas là vous courez le risque de relâcher l'objet. Mais dans cette situation, il semble juste se résumer à la surcharge d'un «si» par rapport à la fréquence de réglage des valeurs en double. – fuzzygoat

Répondre

6

Normalement, vous faites une vérification comme celle-ci dans une méthode de mutateur parce que vous travaillez avec des objets qui doivent être release d. Disons que vous avez une méthode mutateur sans que l'enregistrement:

- (void)setObject:(MyObject *)anObj 
{ 
    [obj release]; 
    obj = [anObj retain]; 
} 

Imaginer (pour une raison quelconque), vous avez un morceau de code comme celui-ci qui utilise cette méthode:

MyObject *o = [MyObject object]; // Auto-released 
[anotherObject setObject:o]; 
[anotherObject setObject:o]; 

Sur la ligne 1, vous pouvez supposer o a un nombre de retenue de 0 (puisqu'il est auto-libéré). Sur la ligne 2, o a été passé à setObject:, qui le conserve et le stocke dans la variable d'instance obj. Étant donné que nous travaillons avec des pointeurs, o et obj pointent vers le même objet en mémoire, qui a maintenant un nombre de retenir 1.

On Line , vous passez le même objet -setObject:à nouveau . Mais tout de suite dans cette méthode, vous publiez anObj, qui est le même objet que o et obj point à! Cela signifie que o, obj et anObj ont un nombre de retenues de . Lorsque vous définissez obj sur [obj retain], vous faites pointer obj vers un objet qui a déjà été publié. Ceci est évidemment mauvais, donc lorsque vous travaillez avec des méthodes mutator qui traitent des objets, vous devez toujours utiliser cette garde, qui vérifie efficacement si obj et anObj pointent vers le même objet en mémoire; s'ils le font, rien ne se passe.

Cependant, cette garde n'est pas nécessaire dans votre exemple, parce que vous passez un int - pas un pointeur - et int s, bien sûr, obtenir leur libération jamais (car ils sont pas des objets) .

+0

Merci Michael (je suppose que c'est vrai) une réponse exceptionnelle très claire, comme d'habitude :) merci beaucoup – fuzzygoat

2

Je ferais votre chemin; l'attribution d'un int est très bon marché. La vérification a un sens si l'affectation concerne une structure de données volumineuse ou peut avoir des effets secondaires inattendus, ce qui n'est pas le cas pour int. L'assignation provoque-t-elle quelque chose à déclencher (événement)?

1

Ça ne semble pas. Vous pouvez comparer, mais pour un int simple, je ne pense pas que ce soit une obligation de vérifier si la valeur est la même ou non. Bien sûr, si vous voulez afficher quelque chose à l'utilisateur concernant le fait qu'il a entré la même valeur, vous pouvez vérifier la valeur, sinon, je ne le vérifierais pas.

Questions connexes