55 votes

Propriétés et Variables d'Instance en Objective-C

Je suis un peu confus sur les propriétés et les variables d'instance en Objective-C.

Je suis environ à mi-chemin par le biais de Aaron Hillegass "Cacao de Programmation pour Mac OS X" et tout est logique. Vous pouvez déclarer une classe à quelque chose comme ceci:

@class Something;

@interface MyClass : NSObject {
    NSString *name;
    NSArray *items;

    Something *something;

    IBOutlet NSTextField *myTextField;
}

@property (nonatomic, retain) NSString *name;
@property (nonatomic, retain) NSArray *items;
  • Depuis d'autres objets ont besoin de manipuler nos name et items variables d'instance, nous utilisons @property/@synthesize pour générer les accesseurs/mutateurs pour eux. Dans notre classe, nous n'avons pas utiliser les accesseurs/mutateurs-nous seulement d'interagir avec la variable d'instance directement.

  • something est juste une variable d'instance que nous allons utiliser dans notre classe, et depuis personne ne doit l'utiliser, nous ne créons pas une paire de accesseurs et des mutateurs.

  • Nous avons besoin d'interagir avec un champ de texte dans notre INTERFACE utilisateur, de sorte que nous déclarer IBOutlet pour, connecter, et nous y sommes.

Tout est très logique.

Cependant, dans l'iPhone monde, les choses semblent différentes. Les gens déclarent propriétés pour chaque variable d'instance, de déclarer des biens pour IBOutlets, et l'utilisation des accesseurs/mutateurs pour interagir avec les variables d'instance au sein de la classe (par exemple, ils écriraient [self setName:@"Test"] plutôt que d' name = @"Test").

Pourquoi? Ce qui se passe? Ces différences propres à l'iPhone? Quels sont les avantages de déclarer des propriétés de toutes les variables d'instance, de déclarer les propriétés de IBOutlets, et l'utilisation des accesseurs/mutateurs au sein de votre propre classe?

29voto

Mehrdad Afshari Points 204872

Dans l'iPhone monde, il n'y a pas de garbage collector disponible. Vous aurez à gérer avec soin la mémoire du comptage de références. Avec cela à l'esprit, considérez la différence entre:

name = @"Test";

et

self.name = @"Test";
// which is equivalent to:
[self setName: @"Test"];

Si vous définissez la variable d'instance, sans examen préalable, vous allez perdre la référence à la valeur précédente et vous ne pouvez pas ajuster ses retain count (vous devriez avoir released manuellement). Si vous y accédez par l'intermédiaire d'un bien, ça va être traitée automatiquement pour vous, avec incrémentation de la conserver comte de nouveau l'objet.

Le concept fondamental est pas l'iPhone, mais il devient essentiel dans un environnement sans le garbage collector.

6voto

stefanB Points 27796

Les propriétés sont utilisées pour générer les accesseurs pour les variables d'instance, il n'y a pas de magie qui se passe.

Vous pouvez implémenter la même accesseurs à la main.

Vous pouvez trouver à Aaron Hillegass du livre des exemples de 3 des stratégies de gestion de la mémoire pour les variables de membre. Ils sont assign/copy/retain. Vous sélectionnez l'une de celles requises pour la variable donnée.

Je suppose que vous comprenez la gestion de la mémoire en Objective-c ...

Les accesseurs de masquer la complexité et les différences de gestion de la mémoire pour chaque variable.

Par exemple:

name = @"Test"

est une simple affectation, name maintenant fait référence à l' NSString @"Test". Cependant, vous pourriez décider d'utiliser copy ou retain. Quelle que soit la version de la gestion de la mémoire que vous avez choisi d'accesseur masque la complexité et vous avez toujours accès à la variable (ou similaire):

[self setName:@"Test"] 
[self name]

Maintenant, setName: peut utiliser assign/copy or retain et vous n'avez pas à vous inquiéter à ce sujet.

Ma conjecture est que l'iPhone tutoriels utiliser les propriétés pour le rendre plus facile pour les nouveaux développeurs à passer par le biais de la gestion de la mémoire (même si c'est pratique pour générer des accesseurs avec des propriétés plutôt que de mettre la main à chaque fois).

3voto

Peter Hosey Points 66275

Cependant, dans l'iPhone monde, les choses semblent différentes. Les gens déclarent propriétés pour chaque variable d'instance, de déclarer des biens pour IBOutlets, et l'utilisation des accesseurs/mutateurs pour interagir avec les variables d'instance au sein de la classe (par exemple, ils écriraient [self setName:@"Test"] plutôt que d' name = @"Test").

Ce n'est pas spécifique pour iPhone. Sauf en init méthodes et l' dealloc méthode, c'est une bonne pratique de toujours utiliser votre accesseurs. Le principal avantage, en particulier sur le Mac (avec le Cacao Liaisons), est que l'utilisation de votre accesseurs gratuit KVO notifications.

La raison pourquoi les gens "déclarer des propriétés pour chaque variable d'instance" qui est le plus probablement que l'ensemble de ses variables d'instance sont des choses qu'ils veulent exposer en tant que propriétés. S'ils avaient quelque chose qu'ils veulent garder privé, ils ne seraient pas déclarer une propriété dans le fichier d'en-tête. (Toutefois, ils peuvent faire une propriété dans une classe de l'extension dans le fichier de mise en oeuvre, afin d'obtenir ladite gratuit KVO notifications.)

Déclarer des propriétés de points de vente est exagéré, à mon avis. Je ne vois pas un point. Si vous ne faites pas une propriété, la plume chargeur permettra de définir la prise en direct de l'instance de la variable d'accès, qui est tout simplement parfait pour cette tâche.

2voto

JRT Points 21

Je voudrais suggérer que le développement moderne a fait une très forte pour tenter d'identifier, de définir et d'appliquer les meilleures pratiques.

Parmi ces bonnes pratiques, nous trouvons la continuité et la cohérence.

En dehors de se disputer à propos de l'utilisation des accesseurs en init et dealloc méthodes accesseurs doivent généralement être utilisés tout le temps (à l'intérieur et à l'extérieur de la classe) pour les avantages qu'ils offrent, y compris l'encapsulation, polymorphe var implémentations (qui permettent à la fois d'abstraire et de refactoring) et pour faciliter les meilleures pratiques de la continuité et de la cohérence. Les avantages fondamentaux d'un objet-orient langue entrent en jeu lors de faire les choses de cette façon et l'exploitation de la plénitude de la langue. Toujours être constant dans son codage est souvent un ci-dessous bénéficient, comme tout programmeur senior généralement en témoigner.

0voto

Shafraz Buhary Points 300

Vous pouvez écrire comme ceci

//MyClass.h

@class Something;

@interface MyClass : NSObject 

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSArray *items;

@end 

//MyClass.m
@interface MyClass() 

@property (nonatomic, strong) IBOutlet NSTextField *myTextField;
@property (nonatomic, strong) Something *something;

@end

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