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



objective c swift (4)

Auparavant, les utilisateurs utilisaient les propriétés publiquement et ivars à des fins privées, mais depuis plusieurs années, vous pouvez également définir des propriétés dans @implementation pour les utiliser en mode privé. Mais j'utiliserais quand même les ivars, car il y a moins de lettres à taper, et ça marche plus vite selon cet article . Il est logique que les propriétés soient "lourdes": elles sont supposées être accessibles à partir de getters / setters générés ou de ceux écrits manuellement.

Cependant, dans les codes récents d'Apple, les ivars ne sont plus utilisés. Je suppose que c'est plus comme objc que C/C++ , plus il est plus facile d'utiliser les propriétés avec assign , nullable , etc.

https://src-bin.com

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

Je ne suis pas très sûr de ça. Je pense qu'une "propriété" est une variable d'instance qui a des méthodes d'accesseur, mais je pourrais penser mal.


Answer #1

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


Answer #2

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é, d'un autre côté, est un attribut de votre objet accessible (cela semble vague et supposé). Généralement, une propriété renvoie ou définit une variable d'instance, mais elle peut utiliser des données de plusieurs ou 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é car il suppose que le nom existe déjà et a au moins deux composants (par exemple "Bill Gates" plutôt que simplement "Gates".) J'ai pensé que la fixation de ces hypothèses ferait le point réel du code moins clair, donc je ne fais que le signaler ici, donc personne ne répète innocemment ces erreurs.)


Answer #3

Une propriété est une façon amicale d'implémenter un getter / setter pour une certaine valeur, avec des fonctionnalités et une syntaxe supplémentaires utiles. Une propriété peut être sauvegardée par une variable d'instance, mais vous pouvez également définir le getter / setter pour qu'il fasse quelque chose de plus dynamique, par exemple vous pouvez définir une propriété lowerCase sur une chaîne qui crée dynamiquement le résultat plutôt que renvoyer la valeur de certains membres variable.

Voici un exemple:

// === In your .h ===

@interface MyObject {
    NSString *propertyName;

}

// ...

@property (nonatomic, retain) NSString *propertyName;

// === In your .m @implementation ===

@synthesize propertyName /* = otherVarName */;

La ligne @property définit une propriété appelée propertyName de type NSString * . Cela peut être obtenu / défini en utilisant la syntaxe suivante:

myObject.propertyName = @"Hello World!";
NSLog("Value: %@", myObject.propertyName);

Lorsque vous affectez ou lisez depuis myObject.propertyName vous appelez vraiment les méthodes setter / getter sur l'objet.

La ligne @synthesize indique au compilateur de générer ces getter / setters pour vous, en utilisant la variable membre avec le même nom de 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 getters / setters en définissant le votre. La convention de nommage pour ces méthodes est setPropertyName: pour le setter et propertyName (ou getPropertyName , pas standard) pour le getter. L'autre sera toujours généré pour vous.

Dans votre ligne @property , vous pouvez définir un certain nombre d'attributs dans les parens pour la propriété qui peut automatiser des choses telles que la sécurité des threads et la gestion de la mémoire. Par défaut, une propriété est atomique, ce qui signifie que le compilateur @synthesiz ed get / set calls avec des verrous appropriés pour éviter les problèmes de concurrence. Vous pouvez spécifier l'attribut nonatomic pour le désactiver (par exemple sur l'iPhone vous voulez par défaut la plupart des propriétés à nonatomic ).

Il existe 3 valeurs d'attribut qui contrôlent la gestion de la mémoire pour tout @synthesized . La première est retain qui enverra automatiquement la release aux anciennes valeurs de la propriété, et retain les nouvelles valeurs. C'est très utile.

La seconde est une copy qui fera une copie de toutes les valeurs passées au lieu de les conserver. Il est recommandé d'utiliser la copy pour NSString, car un appelant peut transmettre un objet NSMutableString et le remplacer par un élément inférieur. copy fera une nouvelle copie de l'entrée à laquelle vous seul avez accès.

La troisième est assign assignée par un pointeur droit sans appel à la fonction de conservation / libération sur l'ancien ou le nouvel objet.

Enfin, vous pouvez également utiliser l'attribut readonly pour désactiver le setter de la propriété.





objective-c