Y a-t-il une différence entre une "variable d'instance" et une "propriété" en Objective-c ?
Je ne suis pas très sûr de ça. Je pense qu'une "propriété" est une variable d'instance qui possède des méthodes d'accès, mais je peux me tromper.
Y a-t-il une différence entre une "variable d'instance" et une "propriété" en Objective-c ?
Je ne suis pas très sûr de ça. Je pense qu'une "propriété" est une variable d'instance qui possède des méthodes d'accès, mais je peux me tromper.
Une propriété est un concept plus abstrait. Une variable d'instance est littéralement juste un emplacement de stockage, comme un emplacement dans une structure. Normalement, les autres objets ne sont jamais censés y accéder directement. Une propriété, en revanche, est un attribut de votre objet qui peut être consulté (cela semble vague et c'est censé être le cas). Habituellement, une propriété renvoie ou définit une variable d'instance, mais elle peut utiliser des données provenant de plusieurs variables ou d'aucune. Par exemple :
@interface Person : NSObject {
NSString *name;
}
@property(copy) NSString *name;
@property(copy) NSString *firstName;
@property(copy) NSString *lastName;
@end
@implementation Person
@synthesize name;
- (NSString *)firstName {
[[name componentsSeparatedByString:@" "] objectAtIndex:0];
}
- (NSString *)lastName {
[[name componentsSeparatedByString:@" "] lastObject];
}
- (NSString *)setFirstName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[NSArray arrayWithObjects:newName, nil] arrayByAddingObjectsFromArray:[nameArray subarrayWithRange:NSMakeRange(1, [nameArray size]-1)]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
- (NSString *)setLastName:(NSString *)newName {
NSArray *nameArray = [name componentsSeparatedByString:@" "];
NSArray *newNameArray [[nameArray subarrayWithRange:NSMakeRange(0, [nameArray size]-2)] arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:newName, nil]];
self.name = [newNameArray componentsJoinedByString:@" "];
}
@end
(Note : Le code ci-dessus est bogué dans la mesure où il suppose que le nom existe déjà et a au moins deux composants (par exemple "Bill Gates" plutôt que juste "Gates"). J'ai pensé que corriger ces hypothèses rendrait le point réel du code moins clair, donc je le signale ici pour que personne ne répète innocemment ces erreurs).
La façon dont j'ai considéré les propriétés est un moyen de fournir/restreindre l'accès aux variables d'instance pour les objets externes. Un peu comme le concept public/privé dans d'autres langues ?
"Normalement, les autres objets ne sont jamais censés y accéder directement" qu'entendez-vous par là ? De plus, votre réponse est-elle mise à jour avec l'Objective-C moderne ?
@Honey Je pense qu'il fait référence au concept d'encapsulation et au respect des meilleures pratiques. Les autres objets ne devraient pas être en mesure d'accéder directement à l'ivar ou de le modifier. En contrôlant l'accès à l'ivar via les propriétés, nous pouvons intercepter ces appels avant qu'ils n'affectent potentiellement l'ivar. Voir ici pour plus d'informations : fr.wikipedia.org/wiki/Encapsulation_(programmation_informatique)
Une propriété est un moyen convivial d'implémenter un getter/setter pour une certaine valeur, avec des caractéristiques et une syntaxe utiles supplémentaires. Une propriété peut être soutenue par une variable d'instance, mais vous pouvez également définir le getter/setter pour faire quelque chose d'un peu plus dynamique, par exemple, vous pouvez définir une propriété lowerCase sur une chaîne de caractères qui crée dynamiquement le résultat plutôt que de renvoyer la valeur d'une variable membre.
Voici un exemple :
// === In your .h ===
@interface MyObject {
NSString *propertyName;
}
// ...
@property (nonatomic, retain) NSString *propertyName;
// === In your .m @implementation ===
@synthesize propertyName /* = otherVarName */;
En @property
définit une propriété appelée propertyName
de type NSString *
. On peut l'obtenir/le définir en utilisant la syntaxe suivante :
myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);
Lorsque vous assignez à ou lisez de myObject.propertyName
vous appelez en fait des méthodes setter/getter sur l'objet.
En @synthesize
indique au compilateur de générer ces getter/setters pour vous, en utilisant la variable membre portant le même nom que la propriété pour stocker la valeur (ou otherVarName
si vous utilisez la syntaxe dans les commentaires).
Avec @synthesize
vous pouvez toujours remplacer l'un des getter/setters en définissant le vôtre. La convention de dénomination de ces méthodes est la suivante setPropertyName:
pour le passeur et propertyName
(ou getPropertyName
(non standard) pour le getter. L'autre sera toujours généré pour vous.
En su @property
vous pouvez définir un certain nombre d'attributs entre parenthèses pour la propriété qui peuvent automatiser des choses comme la sécurité des fils et la gestion de la mémoire. Par défaut une propriété est atomique, ce qui signifie que le compilateur va envelopper @synthesiz
ed avec des verrous appropriés pour éviter les problèmes de concurrence. Vous pouvez spécifier le nonatomic
pour désactiver cette fonction (par exemple, sur l'iPhone, vous souhaitez que la plupart des propriétés soient définies par défaut comme suit nonatomic
).
Il y a 3 valeurs d'attributs qui contrôlent la gestion de la mémoire pour n'importe quel type d'utilisateur. @synthesized
les régleurs. Le premier est retain
qui enverra automatiquement release
aux anciennes valeurs du bien, et retain
aux nouvelles valeurs. Ceci est très utile.
Le second est copy
qui fera une copie de toutes les valeurs transmises plutôt que de les conserver. Une bonne pratique consiste à utiliser copy
pour NSString parce qu'un appelant pourrait passer dans une NSMutableString et la changer sous votre nez. copy
fera une nouvelle copie de l'entrée à laquelle vous seul avez accès.
Le troisième est assign
qui effectue une assignation directe du pointeur sans appeler retain/release sur l'ancien ou le nouvel objet.
Enfin, vous pouvez également utiliser le readonly
pour désactiver le paramètre d'activation de la propriété.
Y a-t-il un avantage à déclarer la variable d'instance et la propriété (par exemple propertyName) ? La déclaration dans l'interface n'est pas nécessaire si vous déclarez une propriété pour la même variable, n'est-ce pas ? Cela permet vraiment d'économiser des lignes de code, à moins qu'il n'y ait quelque chose qui m'échappe
Par défaut, une propriété en lecture-écriture sera soutenue par une variable d'instance, qui sera à nouveau synthétisée automatiquement par le compilateur.
Une variable d'instance est une variable qui existe et conserve sa valeur pendant toute la durée de vie de l'objet. La mémoire utilisée pour les variables d'instance est allouée lors de la création de l'objet (via alloc), et libérée lorsque l'objet est désalloué.
Sauf indication contraire, la variable d'instance synthétisée porte le même nom que la propriété, mais avec un préfixe de soulignement. Pour une propriété appelée firstName, par exemple, la variable d'instance synthétisée sera appelée _firstName.
Auparavant, les gens utilisaient les propriétés publiquement et les ivars pour un usage privé, mais depuis plusieurs années, vous pouvez également définir les propriétés dans @implementation
pour les utiliser en privé. Mais je continuerais à utiliser les ivars quand c'est possible, puisqu'il y a moins de lettres à taper, et que cela fonctionne plus vite d'après cet article . C'est logique puisque les propriétés sont censées être "lourdes" : on est censé y accéder à partir de getters/setters générés ou écrits manuellement.
Cependant, dans les codes récents d'Apple, les ivars ne sont plus utilisés. Je suppose que c'est parce que c'est plus comme objc
plutôt que C/C++
De plus, il est plus facile d'utiliser les propriétés avec les éléments suivants assign
, nullable
etc.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.