web-dev-qa-db-fra.com

@import vs #import - iOS 7

Je m'amuse avec certaines des nouvelles fonctionnalités iOS 7 et travaille avec certains des effets d'image, comme indiqué dans la vidéo de la WWDC "Implémentation de l'interface utilisateur sur iOS". Pour produire un effet de flou dans le code source de la session, UIImage a été étendu via une catégorie qui importe UIKit comme suit:

@import UIKit;

Je pense avoir vu quelque chose à ce sujet dans une autre vidéo de session, mais j'ai du mal à le trouver. Je cherche des informations de base sur le moment d'utiliser ceci. Peut-il être utilisé uniquement avec les frameworks Apple? Les avantages de l’utilisation de cette directive de compilation sont-ils suffisants pour revenir en arrière et mettre à jour l’ancien code?

425
jamdaddy25

C'est une nouvelle fonctionnalité appelée Modules ou "importation sémantique". Il y a plus d'informations dans les vidéos WWDC 201 pour la session 205 et 404 . C'est en quelque sorte une meilleure implémentation des en-têtes pré-compilés. Vous pouvez utiliser des modules avec n’importe quel environnement système dans iOS 7 et Mavericks. Les modules sont un ensemble de l’exécutable du cadre et de ses en-têtes. être plus sûr et plus efficace que #import.

L'un des gros avantages de l'utilisation de @import est que vous n'avez pas besoin d'ajouter le cadre dans les paramètres du projet, cela se fait automatiquement . Cela signifie que vous pouvez ignorer l'étape où vous cliquez sur le bouton plus et recherchez le framework (boîte à outils dorée), puis déplacez-le dans le groupe "Frameworks". Cela épargnera de nombreux développeurs des messages cryptés "Erreur de l'éditeur de liens".

Vous n'avez pas réellement besoin d'utiliser le mot clé @import. Si vous choisissez d'utiliser des modules, tous #import et Les directives #include sont mappées pour utiliser @import automatiquement. Cela signifie que vous n'avez pas besoin de changer votre code source (ni le code source des bibliothèques que vous téléchargez ailleurs). Soi-disant, l'utilisation de modules améliore également les performances de génération, en particulier si vous n'avez pas bien utilisé PCH ou si votre projet contient de nombreux petits fichiers source.

Les modules sont pré-construits pour la plupart des Apple frameworks (UIKit, MapKit, GameKit, etc.). Vous pouvez les utiliser avec les frameworks que vous créez vous-même: ils sont créés automatiquement si vous créez un framework Swift dans Xcode et vous pouvez créer manuellement un fichier ".modulemap" pour tout type Apple ou bibliothèque tierce) .

Vous pouvez utiliser la complétion de code pour voir la liste des frameworks disponibles:

enter image description here

Les modules sont activés par défaut dans les nouveaux projets dans Xcode 5 . Pour les activer dans un projet plus ancien, allez dans les paramètres de construction de votre projet, recherchez "Modules" et définissez "Activer les modules" sur "OUI". Les "cadres de liens" doivent également être "OUI":

Vous devez utiliser Xcode 5 et iOS 7 ou le SDK Mavericks, mais vous pouvez toujours le publier pour les systèmes d'exploitation plus anciens (par exemple iOS 4.3 ou autre). Les modules ne changent pas la manière dont votre code est construit ni aucun code source.


Des diapositives WWDC:

  • Importe la description sémantique complète d'un framework
  • N'a pas besoin d'analyser les en-têtes
  • Meilleure façon d'importer l'interface d'un framework
  • Charge la représentation binaire
  • Plus flexible que les en-têtes précompilés
  • Immunité aux effets des définitions de macros locales (par exemple, #define readonly 0x01)
  • Activé pour les nouveaux projets par défaut

Pour utiliser explicitement les modules:

Remplacez #import <Cocoa/Cocoa.h> par @import Cocoa;

Vous pouvez également importer un seul en-tête avec cette notation:

@import iAd.ADBannerView;

Les sous-modules autocomplete pour vous dans Xcode.

830
nevan king

Belle réponse que vous pouvez trouver dans le livre Learning Cocoa with Objective-C (ISBN: 978-1-491-90139-7)

Les modules constituent un nouveau moyen d'inclure et de relier des fichiers et des bibliothèques à vos projets. Pour comprendre le fonctionnement des modules et leurs avantages, il est important de revenir en arrière dans l'historique d'Objective-C et dans l'instruction #import. Chaque fois que vous souhaitez inclure un fichier à utiliser, vous disposez généralement d'un code ressemblant à ceci:

_#import "someFile.h"
_

Ou dans le cas de frameworks:

_#import <SomeLibrary/SomeFile.h>
_

Etant donné qu’Objective-C est un sur-ensemble du langage de programmation C, l’instruction #import est un raffinement mineur de l’instruction C de _#include_. L'instruction #include est très simple. il copie tout ce qu'il trouve dans le fichier inclus dans votre code lors de la compilation. Cela peut parfois causer des problèmes importants. Par exemple, imaginons que vous ayez deux fichiers d'en-tête: _SomeFileA.h_ et _SomeFileB.h_; _SomeFileA.h_ inclut _SomeFileB.h_, et _SomeFileB.h_ comprend _SomeFileA.h_. Cela crée une boucle et peut confondre le coimpileur. Pour gérer cela, les programmeurs C doivent écrire des gardes contre ce type d’événement.

Lorsque vous utilisez _#import_, vous n'avez pas à vous soucier de ce problème ni à écrire des protecteurs d'en-tête pour l'éviter. Toutefois, _#import_ n’est encore qu’une action glorieuse de copier-coller, ce qui ralentit le temps de compilation entre de nombreux problèmes plus petits mais toujours très dangereux (par exemple, un fichier inclus remplaçant quelque chose que vous avez déclaré ailleurs dans votre propre code). .)

Les modules sont une tentative de contourner ce problème. Ils ne sont plus un copier-coller dans le code source, mais une représentation sérialisée des fichiers inclus pouvant être importés dans votre code source uniquement quand et où ils sont nécessaires. En utilisant des modules, le code se compilera généralement plus rapidement et sera plus sûr que d'utiliser #include ou _#import_.

Revenons à l'exemple précédent d'importation d'un framework:

_#import <SomeLibrary/SomeFile.h>
_

Pour importer cette bibliothèque en tant que module, le code serait remplacé par:

_@import SomeLibrary;
_

Cela a l'avantage supplémentaire de Xcode reliant automatiquement le framework SomeLibrary au projet. Les modules vous permettent également d'inclure uniquement les composants dont vous avez réellement besoin dans votre projet. Par exemple, si vous souhaitez utiliser le composant AwesomeObject dans le cadre AwesomeLibrary, vous devez normalement tout importer pour utiliser le seul élément. Cependant, à l'aide de modules, vous pouvez simplement importer l'objet spécifique que vous souhaitez utiliser:

_@import AwesomeLibrary.AwesomeObject;
_

Pour tous les nouveaux projets réalisés dans Xcode 5, les modules sont activés par défaut. Si vous souhaitez utiliser des modules dans des projets plus anciens (et vous devriez le faire), ils devront être activés dans les paramètres de construction du projet. Une fois que vous avez fait cela, vous pouvez utiliser les deux instructions _#import_ et _@import_ dans votre code, sans aucun souci.

46
gbk

Cela ne fonctionne actuellement que pour les frameworks système intégrés. Si vous utilisez #import comme Apple, le cadre UIKit est toujours importé dans le délégué de l'application, il est remplacé (si les modules sont activés et reconnus comme un cadre système) et le compilateur remappez-le pour qu'il s'agisse d'une importation de module et non d'une importation des fichiers d'en-tête. Donc, laisser le #import sera le même que celui converti en une importation de module si possible

4
RyanTCB

Il semble que depuis XCode 7.x de nombreux avertissements soient émis lors de l'activation du module clang avec CLANG_ENABLE_MODULES

Jetez un oeil à Beaucoup de mises en garde lors de la construction avec Xcode 7 avec des bibliothèques tierces

2
loretoparisi

Un module [Structure] offre une meilleure façon de travailler avec les frameworks et les bibliothèques système en remplaçant le mécanisme d’inclusion de texte du préprocesseur par ce que Clang appelle une importation sémantique. Pour importer un module, utilisez la déclaration _@import_ au lieu des directives de préprocesseur _#include_ ou _#import_.

Lorsque le compilateur voit un module importer _@import_, il charge une version autonome precompiled du binaire. De plus, il gère automatiquement la liaison au module, ce qui vous évite d’ajouter manuellement le framework dans Xcode. Comme le module est compilé une seule fois, il n'y a plus aucun avantage à inclure l'en-tête du framework dans prefix.pch. Par conséquent, le paramètre de construction de l'en-tête de préfixe de précompilation est désormais défini par défaut sur NO dans Xcode.

_@import_ résout les problèmes suivants:

  • Importe la description sémantique complète d'un framework
  • N'a pas besoin d'analyser les en-têtes
  • Charge la représentation binaire
  • Plus flexible que les en-têtes précompilés
  • Pas besoin de maintenir vos fichiers .pch

Les directives _#import_ et _#include_ sont automatiquement converties en _@import_, ce qui vous permet de bénéficier de modules sans aucun travail.

Lorsque vous construisez votre propre framework, Xcode générera une mappe de module incluant le _umbrella header_ [À propos]

Lorsque vous construisez votre propre library en utilisant Objective-C , vous devrez créer votre propre mappe de module (. modulemap ) et assurez-vous que son contenu est à jour. [Créer une bibliothèque][setup modulemap][Modulemap personnalisé]

#mport_ VS _#include

En savoir plus ici , ici

1
yoAlex5

L'utilisation de modules présente quelques avantages. Vous ne pouvez l'utiliser qu'avec le framework Apple, à moins de créer un mappage de modules. @import est un peu similaire à la pré-compilation des fichiers d'en-tête lorsqu'il est ajouté au fichier .pch, qui permet de régler le processus de compilation de l'application. De plus, vous n'avez pas besoin d'ajouter des bibliothèques de la manière habituelle, utiliser @import est beaucoup plus rapide et efficace. Si vous recherchez toujours une bonne référence, je vous recommande fortement de lire cet article .

1
Julian Król