Je peux comprendre la définition des fonctions dans @interface du fichier d'en-tête, mais pourquoi les variables d'instance? Les variables d'instance ne devraient-elles pas être privées, uniquement accessibles par des messages?Pourquoi les variables d'instance sont-elles définies dans le fichier d'en-tête dans Objective-C
Répondre
La raison en est qu'il peut calculer des offsets de variables pour les sous-classes.
@interface Bird : NSObject {
int wingspan;
}
@end
@interface Penguin : Bird {
NSPoint nestLocation;
Penguin *mate;
}
@end
Sans connaître la structure de la classe « Bird », la classe « Penguin » ne peut pas calculer le décalage de ses champs depuis le début de la structure. La structure de pingouin ressemble un peu à ceci:
struct Penguin {
int refcount; // from NSObject
int wingspan; // from Bird
NSPoint nestLocation; // from Penguin
Penguin *mate; // from Penguin
}
Cela a un effet secondaire: si vous modifiez la taille d'une classe dans une bibliothèque, vous briser toutes les sous-classes dans les applications liées à cette bibliothèque. Les nouvelles propriétés fonctionnent autour de ce problème.
Bien qu'elles soient déclarées dans le fichier d'en-tête, toutes les variables d'instance dans Objective-C ont l'accès @protected par défaut. Cela signifie que la variable est accessible dans la classe qui la déclare et toute classe héritant de cette classe.
Voici la documentation d'Apple sur la définition d'une classe Objective-C: Defining Classes
Notez la section intitulée "La portée des variables d'instance".
Tiré de la section de la documentation d'Apple sur la définition des classes Objective-C, The Role of the Interface:
Although instance variables are most naturally viewed as a matter of the implementation of a class rather than its interface, they must nevertheless be declared in the interface file. This is because the compiler must be aware of the structure of an object where it’s used, not just where it’s defined.
Je pense qu'il est un problème technique. Si je comprends bien, une classe Objective-C est juste une structure C fantaisie. Et pour qu'une structure soit utilisée, sa taille doit être connue. (Comme comment sizeof() fonctionnerait autrement)
Notez que sous le nouveau "Modem Runtime" d'Objective C 2.0 (disponible dans les applications iPhone et Mac OS X 10.5 64 bits) vous n'avez pas besoin de spécifier les ivars, vous pouvez spécifier les propriétés, puis utiliser @synthesize pour générer les ivars. Cela s'explique par le fait que dans le moteur d'exécution moderne, les ivars ont un symbole d'indirection global qui contient le décalage pour l'ivar. Cela résout également le problème de classe de base fragile, permettant de réorganiser et d'ajouter des ivars sans nécessiter la recompilation des sous-classes (la suppression ou le renommage des ivars peut toujours provoquer des erreurs de liaison).
Cependant, vous devez toujours lister les propriétés dans l'interface principale, il ne semble donc pas possible de masquer entièrement les ivars privés, ce qui est regrettable. Vous ne pouvez pas, par exemple, utiliser une propriété et @synthesize dans une catégorie.
Vous pouvez cependant déclarer une propriété dans une continuation et @synthesize dans la @implementation principale. –
Au cas où quelqu'un tombe par hasard sur cette question - au XCode 4.2 avec le compilateur LLVM, vous pouvez déclarer des variables d'instance dans la @implementation en utilisant la notation accolade suivante:
@interface SomeClass : NSObject
@end
@implementation SomeClass {
NSString *myInstanceVariable_;
}
- (void)moreMethods {}
@end
Les variables d'instance ne devrait généralement pas faire partie de vos classes déclarées interface publique - ils sont détails de mise en œuvre.
Cependant, MAKE SURE vous définissez vos variables d'instance dans les accolades ou bien vous serez en train de définir une variable globale qui n'a aucun rapport avec l'instance d'objet:
@implementation SomeClass
NSString *whoopsGlobalVariable_;
- (void)moreMethods {}
@end
Je viens d'examiner cela. D'après mes tests, il semble que GCC ne le fera pas; cela donne une erreur: "spécification de variable d'instance incohérente". Il compile uniquement avec LLVM. Voir aussi [Déclaration des variables dans @implementation] (http://stackoverflow.com/questions/7946998/declaring-variables-in-implementation). –
À droite, il nécessite le compilateur LLVM moderne. – sickp
- 1. Comment énumérer toutes les variables définies dans un script groovy
- 2. Quand les variables doivent-elles être définies dans une classe
- 3. Analyseur AMF0 dans ObjectiveC
- 4. Pourquoi mon script Perl ne peut-il pas voir les variables our() que j'ai définies dans un autre fichier?
- 5. Afficher toutes les variables actuellement définies
- 6. Dans ObjectiveC, les pointeurs sont-ils des variables d'instance de classe initialisées à 'nil' ou non?
- 7. actionscript: variables publiques non définies?
- 8. Les variables définies php ont des valeurs nulles
- 9. Comment déplacer des variables non statiques de l'interface à l'implémentation dans objectiveC?
- 10. Pourquoi les variables d'environnement d'un fichier de commandes ne sont-elles pas définies lors de l'exécution de Perl?
- 11. Pourquoi les variables d'environnement de registre visuel ne sont-elles pas définies avec Windows Explorer?
- 12. Pourquoi les méthodes C++ sont-elles parfois définies dans les classes?
- 13. Quand les variables d'instance Ruby sont-elles définies?
- 14. Comment conserver les commentaires sur les variables définies via "M-x customize" sur emacs?
- 15. PHP/Zend se plaint de variables non définies
- 16. Comment Apache Ivy résout-il les variables dans les modèles d'artefacts fournis dans le fichier ivysettings.xml?
- 17. MySQL SELECT INTO OUTFILE et variables définies par l'utilisateur
- 18. Variables dans le fichier batch Windows effectif pour le déploiement?
- 19. Comment obtenir toutes les variables définies dans la portée/table de symboles actuelle?
- 20. Les constantes définies dans environment.rb disparaissent en mode développement
- 21. variable d'environnement dans les variables
- 22. Validation des variables dans le script shell
- 23. Les variables sont-elles définies localement dans un modèle partiel également visible par le modèle erb invoquant?
- 24. Le MiniMock de Python peut-il créer une simulation de fonctions définies dans le même fichier?
- 25. Utilisation de variables d'environnement pour le fichier .config dans .NET
- 26. Comment avertir de l'utilisation de variables non définies dans un script KornShell.
- 27. Pourquoi les globals sont-ils vides dans une classe lorsque les variables sont incluses?
- 28. variables PHP dans les classes
- 29. Traitement des erreurs dans les fonctions définies par l'utilisateur
- 30. Le fichier externe JavaScript n'affiche pas les variables
Ils sont juste C struct , pas même ceux de fantaisie :-) donc quelque chose comme anObject-> anIVar fonctionne très bien. Malheureusement, le runtime hérité autorise ce type d'accès même sur les variables @private et ne vomit qu'un avertissement du compilateur: -/ –