715 votes

@class vs. # import

C'est ma compréhension que l'on devrait utiliser une déclaration de classe dans le cas ClassA doit inclure un ClassB en-tête, et ClassB doit inclure un en-tête ClassA afin d'éviter toute circulaire d'inclusions. Je comprends aussi qu'un #import - il d'une simple ifndef, de sorte que l'inclure n'arrive.

Ma demande est la suivante: Quand est-on utiliser #import et quand doit-on utiliser @class? Parfois, si j'utilise un @class déclaration, je vois une commune d'avertissement du compilateur telles que les suivantes:

warning: receiver 'FooController' is a forward class and corresponding @interface may not exist.

Aimerais vraiment comprendre le présent, à l'opposé d'une suppression de l' @class de l'avant-déclaration et en jetant un #import dans le silence les avertissements du compilateur est de me donner.

756voto

Ben Gottlieb Points 59900

Si vous voyez cet avertissement:

avertissement: récepteur "myCoolClass' est un attaquant de classe et @correspondante de l'interface peut ne pas exister

vous avez besoin d' #import le fichier, mais vous pouvez le faire dans votre fichier d'implémentation (.m), et l'utilisation de l' @class déclaration dans votre fichier d'en-tête.

@class n'a pas (habituellement) de supprimer la nécessité d' #import fichiers, il passe juste à l'exigence de plus près à l'endroit où l'information est utile.

Par Exemple

Si vous dites @class myCoolClass, le compilateur sait qu'il peut voir quelque chose comme:

myCoolClass *myObject;

Il n'a pas à s'inquiéter d'autre chose que de l' myCoolClass est valable pour la catégorie, et il doit réserver la salle pour un pointeur (vraiment, juste un pointeur). Ainsi, dans votre en-tête, @class suffit à 90% du temps.

Toutefois, si jamais vous avez besoin de créer ou accéder myObject's membres, vous aurez besoin de laisser le compilateur de savoir ce que ces méthodes sont. À ce point (sans doute dans votre fichier de mise en oeuvre), vous aurez besoin d' #import "myCoolClass.h", pour indiquer au compilateur des informations supplémentaires au-delà de simplement "c'est classe".

183voto

PeyloW Points 25312

Trois règles simples:

  • Seulement #import la super classe, et les protocoles adoptés, dans les fichiers d'en-tête.
  • #import toutes les classes, et les protocoles, vous envoyez des messages à l'implémentation.
  • Transférer les déclarations pour tout le reste.

Si vous faites une déclaration en avant dans les fichiers d'implémentation, alors vous faites probablement quelque chose de mal.

110voto

Abizern Points 52378

Regardez l'Objective-C, Langage de Programmation de la documentation sur les ADC

En vertu de la section sur la Définition d'une Classe | Catégorie d'Interface, il explique pourquoi c'est fait:

@Directive de classe réduit la quantité de code vu par le compilateur et l'éditeur de liens, et est donc la façon la plus simple de donner une déclaration anticipée d'un nom de classe. Être simple, ça évite les problèmes potentiels qui peuvent venir avec de l'importation de fichiers importer d'autres fichiers. Par exemple, si une classe déclare un typage statique variable d'instance d'une autre classe, et leurs deux interface d'importation des fichiers les uns des autres, ni de classe peut compiler correctement.

J'espère que cette aide.

48voto

Marc Charbonneau Points 30464

Utiliser une déclaration anticipée dans le fichier d'en-tête si nécessaire, et #import les fichiers d'en-tête pour toutes les classes que vous utilisez dans la mise en œuvre. En d'autres termes, vous avez toujours l' #import les fichiers que vous utilisez dans votre application, et si vous avez besoin de faire référence à une classe dans votre fichier d'en-tête d'utiliser une déclaration anticipée.

L' exception à cela est que vous devriez #import une classe ou d'un protocole officiel vous êtes à hériter de dans votre fichier d'en-tête (auquel cas vous n'auriez pas besoin de l'importer dans la mise en œuvre).

24voto

vent Points 429

Un autre avantage: la compilation rapide

Si vous incluez un fichier d'en-tête, toute modification entraîne la compilation du fichier en cours, mais ce n'est pas le cas si le nom de classe est inclus en tant que @class name . Bien sûr, vous devrez inclure l'en-tête dans le fichier source

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