Depuis que j'ai commencé à travailler sur les applications iOS et l'objectif C, j'ai été vraiment intrigué par les différents endroits où l'on pouvait déclarer et définir des variables. D'une part, nous avons l'approche traditionnelle C, d'autre part, nous avons les nouvelles directives ObjectiveC qui ajoutent OO en plus de cela. Pourriez-vous m'aider à comprendre les meilleures pratiques et les situations dans lesquelles je voudrais utiliser ces emplacements pour mes variables et peut-être corriger ma compréhension actuelle?
Voici un exemple de classe (.h et .m):
#import <Foundation/Foundation.h>
// 1) What do I declare here?
@interface SampleClass : NSObject
{
// 2) ivar declarations
// Pretty much never used?
}
// 3) class-specific method / property declarations
@end
et
#import "SampleClass.h"
// 4) what goes here?
@interface SampleClass()
// 5) private interface, can define private methods and properties here
@end
@implementation SampleClass
{
// 6) define ivars
}
// 7) define methods and synthesize properties from both public and private
// interfaces
@end
- Ma compréhension de 1 et 4 est que ce sont des déclarations et des définitions basées sur des fichiers de style C qui n'ont aucune compréhension du concept de classe, et doivent donc être utilisées exactement comme elles seraient utilisées en C. Je les ai vues utilisé auparavant pour implémenter des singletons statiques basés sur des variables. Y a-t-il d'autres utilisations pratiques qui me manquent?
- Mon expérience avec iOS est que les ivars ont été presque complètement supprimés en dehors de la directive @synthesize et peuvent donc être ignorés. Est-ce le cas?
- Concernant 5: pourquoi voudrais-je déclarer des méthodes dans des interfaces privées? Mes méthodes de classe privée semblent bien compiler sans déclaration dans l'interface. Est-ce principalement pour la lisibilité?
Merci beaucoup, les amis!
la source
Tout d'abord, lisez la réponse de @ DrummerB. C'est un bon aperçu des pourquoi et de ce que vous devez généralement faire. Dans cet esprit, à vos questions spécifiques:
Aucune définition de variable réelle n'est disponible ici (il est techniquement légal de le faire si vous savez exactement ce que vous faites, mais ne le faites jamais). Vous pouvez définir plusieurs autres types de choses:
Les externes ressemblent à des déclarations de variables, mais ils ne sont qu'une promesse de le déclarer ailleurs. Dans ObjC, ils ne doivent être utilisés que pour déclarer des constantes, et généralement uniquement des constantes de type chaîne. Par exemple:
Vous
.m
déclareriez alors dans votre fichier la constante réelle:Comme l'a noté DrummerB, c'est un héritage. Ne mettez rien ici.
Oui.
Constantes externes, comme décrit ci-dessus. Les variables statiques de fichier peuvent également aller ici. Ce sont l'équivalent des variables de classe dans d'autres langues.
Oui
Mais très rarement. Presque toujours, vous devriez autoriser clang (Xcode) à créer les variables pour vous. Les exceptions concernent généralement les ivars non-ObjC (comme les objets Core Foundation, et en particulier les objets C ++ s'il s'agit d'une classe ObjC ++), ou les ivars qui ont une sémantique de stockage étrange (comme les ivars qui ne correspondent pas à une propriété pour une raison quelconque).
Généralement, vous ne devriez plus @synthesize. Clang (Xcode) le fera pour vous, et vous devriez le laisser.
Ces dernières années, les choses se sont considérablement simplifiées. L'effet secondaire est qu'il existe maintenant trois époques différentes (ABI fragile, ABI non fragile, ABI non fragile + auto-syntheisze). Donc, quand vous voyez l'ancien code, cela peut être un peu déroutant. Ainsi confusion découlant de la simplicité: D
la source
Je suis aussi assez nouveau, alors j'espère que je ne gâche rien.
1 & 4: Variables globales de style C: elles ont une portée étendue au fichier. La différence entre les deux est que, puisqu'ils sont à l'échelle du fichier, le premier sera disponible pour quiconque importe l'en-tête tandis que le second ne l'est pas.
2: variables d'instance. La plupart des variables d'instance sont synthétisées et récupérées / définies via des accesseurs en utilisant des propriétés car cela rend la gestion de la mémoire agréable et simple, ainsi que vous donne une notation par points facile à comprendre.
6: Les ivars de mise en œuvre sont quelque peu nouveaux. C'est un bon endroit pour mettre des ivars privés, car vous ne voulez exposer que ce qui est nécessaire dans l'en-tête public, mais les sous-classes ne les héritent pas d'AFAIK.
3 & 7: Déclarations de méthodes et de propriétés publiques, puis implémentations.
5: interface privée. J'utilise toujours des interfaces privées chaque fois que je peux pour garder les choses propres et créer une sorte d'effet de boîte noire. S'ils n'ont pas besoin de le savoir, mettez-le là. Je le fais aussi pour la lisibilité, je ne sais pas s'il y a d'autres raisons.
la source
Ceci est un exemple de toutes sortes de variables déclarées en Objective-C. Le nom de la variable indique son accès.
Fichier: Animal.h
Fichier: Animal.m
Notez que les variables iNotVisible ne sont visibles depuis aucune autre classe. C'est un problème de visibilité, donc les déclarer avec
@property
ou@public
ne le change pas.À l'intérieur d'un constructeur, il est recommandé d'accéder aux variables déclarées avec un
@property
trait de soulignementself
pour éviter les effets secondaires.Essayons d'accéder aux variables.
Fichier: Cow.h
Fichier: Cow.m
Nous pouvons toujours accéder aux variables non visibles en utilisant le runtime.
Fichier: Cow.m (partie 2)
Essayons d'accéder aux variables non visibles.
Fichier: main.m
Cette imprime
Notez que j'ai pu accéder au support ivar
_iNotVisible2
qui est privé pour la sous-classe. En Objective-C, toutes les variables peuvent être lues ou définies, même celles qui sont marquées@private
, sans exception.Je n'ai pas inclus les objets associés ou les variables C car ce sont des oiseaux différents. Comme pour les variables C, toute variable définie en dehors
@interface X{}
ou@implementation X{}
est une variable C avec une portée de fichier et un stockage statique.Je n'ai pas discuté des attributs de gestion de la mémoire, ni des attributs de lecture seule / readwrite, getter / setter.
la source