web-dev-qa-db-fra.com

Variables d'instance déclarées dans le fichier de mise en œuvre de l'OBJC

Je regardais la vidéo d'introduction de la WWDC Arc et j'ai vu quelque chose que je n'ai jamais vu dans Objc auparavant lorsque certains Apple ingénieur ont parlé d'un exemple de pile.

Le code suivant a été utilisé pour un exemple de pile avec ARC:

@implementation Stack 
{ 
    // instance variable declared in implementation context
    NSMutableArray *_array; 
}

- (id)init 
{
   if (self = [super init])
      _array = [NSMutableArray array];
   return self;
}

- (void)Push:(id)x 
{
   [_array addObject:x];
}

- (id)pop 
{
   id x = [_array lastObject];
   [_array removeLastObject];
   return x;
}

@end

Veuillez noter la variable d'instance déclarée juste après la directive @ implémentation.

Maintenant, la chose qui m'a surpris, c'est qu'une variable d'instance pourrait réellement être déclarée dans le fichier de mise en œuvre, sans qu'il soit une variable statique. Mes questions seraient les suivantes:

  • Est-ce que ceci est une nouvelle construction introduite dans le SDK pour iOS 5 ou cela a-t-il été possible pendant une longue période?
  • Serait-ce une bonne pratique de déclarer des variables d'instance dans la mise en œuvre, si les variables d'instance ne doivent pas être consultées en dehors de l'objet? Il semble plus propre que l'utilisation de la directive @private.
47
Wolfgang Schreurs

C'est en effet une nouvelle fonctionnalité linguistique, et si vous devez déclarer vos ivars (plutôt que simplement déclarer des propriétés et laisser le compilateur générer des ivars pour vous) c'est une bonne pratique. Vos fichiers d'en-tête en théorie ne doivent exposer que l'interface publique pour vos classes; Tout le reste appartient à la mise en œuvre.

Une mise en garde est que les ivars-fichier de mise en œuvre ne sont pas visibles pour les sous-classes, qui peuvent parfois être un peu maladroites si vous avez généré manuellement des seigurs et des getters que vous devez sousclure.

40
Seamus Campbell

Déclarer des ivars à l'intérieur de la mise en œuvre est définitivement une nouvelle construction de l'objectif C. Vous devez utiliser XCode4.2 et avoir le compilateur LLVM sélectionné dans vos paramètres de construction. L'idée est de garder votre en-tête dossier plus propre. Vous pouvez énumérer vos ivars à l'intérieur des accolades bouclés comme cet exemple;

@implementation MyClass {    
  int var1;
  int var2;
}

La réponse donnée par Rahul n'est pas vraiment correcte, même si vous pouvez supprimer des variables de la manière dont il dit qu'ils seraient considérés comme statiques par le compilateur. Probablement pour les cas dans lesquels il les utilisait, il n'a pas d'importance.

18
David Temple

Je suis nouveau dans l'objectif C et j'ai trouvé la pratique de déclarer des ivars dans l'en-tête très étrange. Cela signifie déclarer l'état interne d'un objet dans son en-tête public, qui défie le concept d'encapsulation.

Par exemple, disons que vous possédez un iPad. =Apple== NE VOULEZ PAS que vous brisez l'iPad Ouvrez et sommez-vous et dégageez-vous avec les éléments à l'intérieur. S'ils veulent que vous modifiez quelque chose, l'iPad aura un paramètre qui vous permettra de changer cela.

De même, je ne veux pas que d'autres programmeurs voient les ivars de mes objets. C'est l'état interne de mon objet. Si je veux que vous soyez dans l'état interne, je déclare les propriétés pour cela.

Ainsi, comme dans d'autres langues, je cacherais mes ivars à l'intérieur du facteur de concevoir et ne les déclarerais pas dans l'en-tête.

Déclarant des ivars dans l'en-tête me frappe comme très très étrange. Ces ivars sont spécifiques à la mise en œuvre et ne doivent tout simplement pas faire partie du fichier d'en-tête.

3
Leander