Comment déclarer des variables d'instance et des méthodes non visible ou utilisable en dehors de l'instance de classe?
J'ai regardé à travers un tas de posts sur ce sujet. Peut-être que je n'ai pas couru à travers "l'un" et quelqu'un va me pointer dans cette direction. La question est simple et probablement a une réponse simple.
Si vous avez deux ivars, disons, "public_ivar" et "private_ivar", où/comment devez-vous déclarer, de sorte que ce qui est public est public et ce qui est privé n'est pas exposé à tous ceux qui cherchent à l'en-tête de fichier?
Même question dans le cas de "public_method" et "private_method".
J'aime nettoyer les fichiers d'en-tête (dans d'autres langues) que seulement exposer les méthodes et les ivars je veux que quelqu'un d'autre à voir. Vous devriez être en mesure de publier votre fichier d'en-tête et pas dans le danger de quelqu'un accès à quelque chose qu'ils ne sont pas censé le faire. Comment faites-vous cela en objective-C.
Par exemple, disons que j'ai décider que j'ai besoin d'utiliser un ivar pour garder la trace de certaines données, d'un comptoir ou quelque chose comme ça, entre les différentes méthodes de la classe qui ont besoin d'accéder à ces informations. Si ivar est déclaré de manière conventionnelle dans l'en-tête sous @interface de son existence est annoncé publiquement et il est utilisable par n'importe qui de créer une instance de la classe. Le scénario idéal serait que ce ivar ne serait pas visible à l'extérieur de l'implémentation de la classe.
OriginalL'auteur martin's | 2011-04-28
Vous devez vous connecter pour publier un commentaire.
Vous pouvez déclarer des variables d'instance ou déclarées propriétés dans une extension de classe. Depuis une extension de classe est déclarée dans un fichier d'implémentation (c'est à dire, pas un fichier d'en-tête), ils ne seront pas visibles pour quelqu'un inspecter le fichier d'en-tête. Par exemple, dans le fichier d'en-tête:
et dans la mise en œuvre de fichier:
ou
Remarque qu'il n'y a rien qui empêche l'accès privé/extension de classe variables d'instance (ou les méthodes d'accès pour les propriétés déclarées dans une classe d'extension) au cours de l'exécution. J'ai écrit une assez détaillées post à ce sujet comme une réponse à une autre question sur Stack Overflow: N'privé @property créer un @privée variable d'instance?
Edit: variables d'Instance dans les extensions de la classe ont été présentés dans la WWDC 2010 session 144.
Edit: "à l'Aide de la Clang/LLVM 2.0 compilateur, vous pouvez également déclarer les propriétés et les variables d'instance dans une extension de classe."
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocCategories.html#//apple_ref/doc/uid/TP30001163-CH20-SW1
Je ne suis pas sûr lors de l'Objective-C 2.0, qui permet la création automatique de la sauvegarde des variables d'instance, a été rendu disponible pour iOS.
href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtVersionsPlatforms.html%23//apple_ref/doc/uid/TP40008048-CH106-SW1" >Cette page sur le site Web d'Apple n'a pas de liste particulière de la version iOS.
Êtes-vous sûr que vous pouvez ajouter ivars directement dans les extensions? La référence ne dit rien à ce sujet. Vous pouvez poster une référence, ou est-ce juste une expérience personnelle?
L'expérience personnelle; je pense que ce qui a été disponible depuis Clang 2.0. Si vous pensez que ce n'est pas documentée, il ne faut pas compter sur elle, j'ai en quelque sorte d'accord avec vous. Mais j'ai un fort sentiment que cela va faire Apple de l'Objective-C référence, car il n'y a pas de dommages apparents et les modernes runtime ABI prise en charge non-fragile, les variables d'instance.
OriginalL'auteur
Utilisation les extensions de la classe à ajouter à une classe dans votre fichier de mise en oeuvre. Une extension de classe est à la base un sans nom, catégorie, avec quelques bonus: propriétés déclarées dans il peut être synthétisé et rien déclaré dans il doit être dans la principale de la mise en œuvre, de sorte que le compilateur peut assurez-vous que vous ne manquez pas une mise en œuvre. Vous devez mettre l'extension de classe avant votre mise en œuvre. Vous ne pouvez pas ajouter des variables d'instance directement dans une extension de classe, mais vous pouvez ajouter des propriétés. Lorsque vous synthétiser des accesseurs pour les propriétés qui n'ont pas de correspondant variables d'instance, le nouveau moteur d'exécution (os x 10.5 et versions ultérieures, et toutes les versions d'iOS, je crois) va créer les variables d'instance automatiquement. Cela signifie que vous ne pouvez pas créer votre propre accesseurs, cependant, sauf si vous mettez la variable d'instance dans votre en-tête. Les méthodes privées peut être ajouté à la classe d'extension sans restriction, mais comme l'Anomie de le noter, il est techniquement possible de les utiliser si vous savez ce qu'ils sont appelés, et avec la classe de vidage, rien n'est sûr.
Exemple d'utilisation d'une extension de classe:
Une autre façon de créer des "variables d'instance" sans les mettre dans l'en-tête ou en utilisant une propriété est d'utiliser associatif références, ajouter des données à un objet lors de l'exécution. Ils ne sont pas techniquement la même chose que les variables d'instance, et la syntaxe est plus complexe. Depuis, ils ont aussi besoin de la nouvelle de l'exécution, il y a seulement deux raisons dont vous avez vraiment envie de les utiliser: vous souhaitez ajouter une variable d'instance dans une catégorie (en dehors de la portée de cette question) ou vous en avez besoin pour être vraiment vraiment privé. Associatif de référence ne crée pas de méthodes ou de l'ajouter à la classe de définition dans le code compilé, donc si vous ne créez pas des wrappers pour eux, il est impossible de les trouver sans demander de l'objet lorsque vous ajoutez des données. Voir le bas de la page complète pour un exemple d'utilisation.
Comme Bavarious dit, et comme indiqué dans les commentaires, ivars sont désormais pris en charge dans les extensions de la classe, de sorte que vous pouvez le déclarer de là, au lieu de l'en-tête. Vous pouvez également utiliser associatif références et d'écrire des wrappers autour d'eux comme des accesseurs.
OriginalL'auteur
Vous pouvez utiliser
@private
de préciser que ivars sont privés. Il n'y a aucun moyen de faire une méthode privée, cependant. Même si la méthode n'est pas répertorié dans le fichier d'en-tête, si quelqu'un connaît le nom et les arguments qu'ils peuvent appeler.Une propriété n'est pas un ivar. Comme pour cacher ivars dans l'en-tête, je pense à deux options: Vous pourriez être le seul ivar être un pointeur vers une struct qui est déclarée ailleurs, ou vous pourriez avoir tous les cas, en être privé sous-classes (à l'instar de ce que fait Apple avec des clusters de classe).
Coupable d'être paresseux avec la langue. Je comprends que les @property crée simplement le sous-jacent setter et getter code. Faut-il faire autre chose?
n'a même pas de créer le sous-jacent setter et getter. Il indique au compilateur que la
foo.property
syntaxe doit utiliser le getter et le setter de la méthode, et permet de @synthétiser de travail. Et un peu de comptabilité, de sorteclass_getProperty
et d'autres méthodes peuvent faire leur travail.OriginalL'auteur