Question

Je suis en train de comprendre le but de la directive synthesize avec dépassement du nom de la propriété. Dire que j'ai une interface définie comme suit:

@interface Dummy ... {
    UILabel *_dummyLabel;
}

@property (retain, nonatomic) UILabel *dummyLabel;

Et dans le fichier de mise en œuvre, je:

@synthesize dummyLabel = _dummyLabel;

D'après ce que je comprends, "dummyLabel" est juste un alias de la variable d'instance "_dummyLabel". Est-il une différence entre self._dummyLabel et self.dummyLabel?

Était-ce utile?

La solution

Oui. self._dummyLabel est non défini, mais _dummyLabel est pas.

syntaxe Dot se développe vers des invocations simples de la méthode, il est donc pas spécifique aux propriétés. Si vous avez une méthode appelée -(id)someObject, par exemple dans le cas de object.someObject, ce sera comme si vous avez écrit [object someObject];.

self.dummyLabel  //works
self._dummyLabel //does not work
dummyLabel       //does not work
_dummyLabel      //works
[self dummyLabel];  //works
[self _dummyLabel]; //does not work

Autres conseils

Votre compréhension est incorrecte. dummyLabel est le nom de la propriété, et est pas un alias pour la variable d'instance - la variable d'instance est uniquement appelé _dummyLabel. Donc, ce qui suit est une instance de Dummy appelé myObject:

  • [myObject dummyLabel] fonctionne
  • myObject.dummyLabel fonctionne
  • [myObject _dummyLabel] échoue
  • myObject._dummyLabel échoue
  • myObject->dummyLabel échoue
  • myObject->_dummyLabel dépend de la visibilité du Ivar (@public, @private, @protected)
  • [myObject valueForKey: @"dummyLabel"] fonctionne
  • [myObject valueForKey: @"_dummyLabel"] dépend de la mise en œuvre de +accessInstanceVariablesDirectly (à savoir qu'il fonctionne dans le cas par défaut où retourne +accessInstanceVariablesDirectly YES).
  

L'avantage d'avoir un autre nom   pour la Ivar que pour la propriété est   que vous pouvez facilement voir dans le code   lorsque vous accédez à un ou   autre - Andre K

Je ne suis pas en mesure de trouver un bouton « commentaire » alors je vais avoir à poster comme une « réponse ».

Je voulais juste développer sur le commentaire d'André - en sachant quand vous utilisez les propriétés de synthèse contre la variable de vanille, vous savez (surtout en cas de setters) lorsqu'une variable est conservée / copiés / libérés automatiquement grâce à votre beau setter , vs être manipulé par la main.

Bien sûr, si vous faites les choses, vous ne avez probablement pas besoin de l'aide d'un poseur de conserver / libération des objets correctement! Mais il peut y avoir d'autres scénarios trop où se référant à vos Ivars comme self.ivar au lieu de _ivar peut être utile, par exemple lorsque vous utilisez setters personnalisés / getters au lieu de ceux par défaut de synthèse. Peut-être que chaque fois que vous modifiez une propriété, vous souhaitez aussi stocker à NSUserDefaults. Donc, vous pourriez avoir un code comme ceci:

@interface SOUserSettings : NSObject {

BOOL _autoLoginOn;

}

@property (nonatomic, assign) BOOL autoLoginOn;

@end

@implementation SOUserSettings

@synthesize autoLoginOn = _autoLoginOn;

- (void)setAutoLoginOn:(BOOL)newAutoLoginOnValue {

   _autoLoginOn = newAutoLoginOnValue;
   [[NSUserDefaults standardUserDefaults] setBool:_autoLoginOn forKey:@"UserPrefAutoLoginOn"];
}

@end

Note: Ceci est juste un code d'illustration, il pourrait y avoir mille choses mal avec elle

Alors maintenant, dans votre code, si vous avez une ligne qui dit _autoLoginOn = YES -. Vous savez que ça ne va pas être sauvé à NSUserDefaults, alors que si vous utilisez self.autoLoginOn = YES vous savez exactement ce qui va se passer

La différence entre _autoLoginOn et self.autoLoginOn est plus que sémantique.

  

Je ne vois pas de gros avantage de   renommer _dummyLabel à dummyLabel

Dans certains runtimes ObjC vous avez du mal à faire des variables d'instance invisible pour les utilisateurs de la classe. Pour les coller certains préfixe (ou suffixe) sur vos variables d'instance peut préciser (ou plus clair) que vous ne voulez pas que quelqu'un de jouer avec vos variables. Cependant, vous ne voulez pas que vos gunk fonctions publiques. Cela vous permet de l'enlever.

Il pourrait également être utile si vous avez besoin de maintenir une ancienne interface avec un ensemble de noms en même temps que d'une nouvelle série d'API avec une nouvelle série de noms (setLastname contre setSurname).

Ancien poste, mais je pense qu'il est important de mentionner qu'il est recommandé d'accéder à des variables via des accesseurs (donc, avec la notation par points). L'accès est fortement recommandé directement un champ (_ivar) seulement quand initialisant.

Il y a l'article de quelques bonnes d'Apple: https://developer.apple.com/ bibliothèque / ios / # documentation / cacao / conceptuel / ProgrammingWithObjectiveC / EncapsulatingData / EncapsulatingData.html

Au dernier paragraphe:

  

Vous devriez toujours accéder directement aux variables d'instance de l'intérieur   une méthode d'initialisation, car au moment où une propriété est définie, la   reste de l'objet ne peut pas encore être complètement initialisé. Même si vous   ne fournissent pas des méthodes d'accès personnalisé ou connaissez des effets secondaires de   au sein de votre propre classe, une sous-classe future peut passer outre très bien la   comportement.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top