399 votes

Quelle est la différence entre #import et #include en Objective-C ?

Quelles sont les différences entre #import et #include en Objective-C et y a-t-il des moments où vous devez utiliser l’une sur l’autre ? Est un obsolète ?

J’ai lu le tutoriel suivant : http://www.otierney.net/objective-c.html#preamble et son paragraphe sur #import et #include semble se contredire, ou au moins n’est pas claires.

373voto

Sven Points 13090

Il semble y avoir beaucoup de confusion concernant le préprocesseur.

Ce que le compilateur ne quand il voit un #include qu'il remplace cette ligne avec le contenu des fichiers inclus, sans poser de questions.

Donc, si vous avez un fichier a.h avec ce contenu:

typedef int my_number;

et un fichier b.c avec ce contenu:

#include "a.h"
#include "a.h"

le fichier b.c seront traduits par le préprocesseur avant la compilation de

typedef int my_number;
typedef int my_number;

ce qui résultera en une erreur de compilation, puisque le type my_number est définie deux fois. Même si la définition est la même, ce n'est pas permis par le langage C.

Depuis un en-tête est souvent utilisé en plus d'un lieu d'inclure les gardes sont généralement utilisés en C. Cela ressemble à ceci:

 #ifndef _a_h_included_
 #define _a_h_included_

 typedef int my_number;

 #endif

Le fichier b.c encore l'ensemble du contenu de l'en-tête en deux fois après avoir été prétraitées. Mais, dans le deuxième exemple, pourrait être ignorée, car la macro _a_h_included_ ont déjà été définis.

Cela fonctionne vraiment bien, mais elle a deux inconvénients. Tout d'abord inclure les gardes les ont écrites, et le nom de la macro doit être différente dans chaque en-tête. Et d'autre part que le compilateur doit toujours rechercher le fichier d'en-tête et de le lire autant de fois qu'il est inclus.

Objective-C a l' #import instructions de préprocesseur (il peut également être utilisé pour le code C et C++ avec certains compilateurs et des options). Cela fait à peu près la même que #include, mais il prend également note interne de laquelle le fichier a déjà été inclus. L' #import ligne est remplacé par le contenu du fichier nommé pour la première fois, il est rencontré. Chaque fois qu'il est simplement ignoré.

356voto

Jason Coco Points 52303

La directive #import a été ajouté à Objective-C comme une version améliorée de #include. Qu'il soit ou non améliorée, cependant, est encore un sujet de débat. #import assure qu'un fichier n'est jamais inclus la fois de sorte que vous n'aurez jamais un problème avec récursive. Cependant, la plupart des bons fichiers d'en-tête de se protéger contre ce de toute façon, il n'est donc pas vraiment un avantage.

En gros, c'est à vous de décider lequel vous souhaitez utiliser. J'ai tendance à #import des en-têtes pour Objet C de choses (comme les définitions de classe) et #include standard C des trucs dont j'ai besoin. Par exemple, un de mes fichiers sources pourrait ressembler à ceci:

#import <Foundation/Foundation.h>

#include <asl.h>
#include <mach/mach.h>

65voto

user512705 Points 441

Je suis d'accord avec Jason.

Je me suis fait piéger en faisant ceci:

#import <sys/time.h>  // to use gettimeofday() function
#import <time.h>      // to use time() function

Pour GNU gcc, il continuait à se plaindre de la fonction time() a été pas défini.

Alors j'ai changé de #import pour #include et tout s'est bien passé.

Raison:

Vous #import <sys/time.h>:
<sys/time.h> ne comprend qu'une partie de <time.h> en utilisant #définit

Vous #import <time.h>:
Sans aller. Même si seulement une partie de <time.h> a déjà été inclus, comme
la mesure de #import est concerné, ce fichier est d'ores et déjà complètement inclus.

Bas de ligne:

C/C++ en-têtes traditionnellement comprend des pièces d'autres fichiers à inclure.
Ainsi, pour le C/C++ en-têtes, utiliser #include.
Pour objc/objc++ en-têtes, l'utilisation de #import.

26voto

Ferruccio Points 51508

fonctionne exactement comme la C .

``suivi des en-têtes ont déjà été inclus et est ignoré si un en-tête est importé plus d’une fois dans une unité de compilation. Ce qui rend inutile l’utilisation de gardes de l’en-tête.

Le résultat est simplement utiliser `` en Objective-C et ne vous inquiétez pas si vos en-têtes liquidez importer quelque chose de plus d’une fois.

14voto

alex gray Points 5089

Je sais que ce fil est vieux... mais dans "les temps modernes".. il est de loin supérieur à la "stratégique" par clang l' @import modules - qui est souvent négligé..

Les Modules d'améliorer l'accès à l'API de bibliothèques logicielles, en remplaçant le texte de préprocesseur inclusion modèle avec un plus robuste, plus efficace modèle sémantique. À partir de la perspective de l'utilisateur, le code est légèrement différent, car on utilise une déclaration d'importation plutôt que d'un #include directive de préprocesseur:

@import Darwin; // Like including all of /usr/include. @see /usr/include/module.map

ou

@import Foundation;  //  Like #import <Foundation/Foundation.h>
@import ObjectiveC;  //  Like #import <objc/runtime.h>

Cependant, ce module d'importation se comporte tout à fait différemment de la correspondante #: lorsque le compilateur voit le module d'importation ci-dessus, il charge d'une représentation binaire du module et fait de son API disponibles pour l'application directement. Définitions de préprocesseur qui précèdent la déclaration d'importation n'ont pas d'impact sur l'API fournie... parce que le module a été compilé séparément, module autonome. En outre, les drapeaux de l'éditeur de liens nécessaires pour utiliser le module sera automatiquement être fourni lorsque le module est importé. Cette sémantique importer le modèle traite de nombreux problèmes de la préprocesseur inclusion modèle.

Pour activer les modules, passer l'indicateur de ligne de commande -fmodules aka CLANG_ENABLE_MODULES en Xcode- au moment de la compilation. Comme mentionné ci-dessus.. cette stratégie évite TOUTE et à TOUS, LDFLAGS. Comme dans, vous pouvez SUPPRIMER tout "OTHER_LDFLAGS" paramètres", ainsi que tous les "Liens" phases..

enter image description here

Je trouve compiler / temps de lancement de "ressentir" beaucoup plus active (ou peut-être, il y a juste moins de lag alors que les "liens"?).. et aussi, fournit une excellente occasion de purger le maintenant étrangères Projet de Préfixe.pch fichier et les paramètres de construction, GCC_INCREASE_PRECOMPILED_HEADER_SHARING, GCC_PRECOMPILE_PREFIX_HEADER, et GCC_PREFIX_HEADER, etc.

Aussi, tout n'est pas bien documentée... Vous pouvez créer module.maps pour vos propres cadres et de les inclure dans la même façon pratique. Vous pouvez prendre un coup d'oeil à mon ObjC-Clang-Modules de dépôt github pour quelques exemples de la façon de mettre en œuvre de tels miracles.

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