84 votes

Y a-t-il une différence entre une "variable d'instance" et une "propriété" en Objective-c ?

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.

87voto

Chuck Points 138930

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).

4 votes

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 ?

0 votes

"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 ?

1 votes

@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)

34voto

Mike Weller Points 28387

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é.

1 votes

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

6voto

Jens Busch Points 82

J'utilise les propriétés pour la partie interface - où l'objet s'interface avec d'autres objets. et les variables d'instance sont des éléments dont vous avez besoin à l'intérieur de votre classe - personne d'autre que vous n'est censé les voir et les manipuler.

3voto

jitenagarwal19 Points 198

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.

2voto

superarts.org Points 685

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.com

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.

Powered by:

X