461 Stimmen

@import vs #import - iOS 7

Ich spiele mit einigen der neuen iOS 7-Funktionen herum und arbeite mit einigen der Bild-Effekte, wie sie im WWDC-Video "Engagierende UI auf iOS implementieren" diskutiert werden. Um einen Weichzeichnungseffekt innerhalb des Quellcodes für die Sitzung zu erzeugen, wurde UIImage über eine Kategorie erweitert, die UIKit wie folgt importiert:

@import UIKit;

Ich glaube, ich habe etwas dazu in einem anderen Sitzungsvideo gesehen, aber ich habe Schwierigkeiten, es zu finden. Ich suche nach Hintergrundinformationen darüber, wann ich das verwenden sollte. Kann es nur mit Apple-Frameworks verwendet werden? Sind die Vorteile der Verwendung dieser Compilerdirektive ausreichend, dass ich zurückgehen und alten Code aktualisieren sollte?

870voto

nevan king Punkte 110579

Es handelt sich um eine neue Funktion namens Module oder "semantische Importierung". Weitere Informationen finden sich in den WWDC 2013 Videos für die Sitzung 205 und 404. Es handelt sich um eine bessere Implementierung der vorkompilierten Header. Sie können Module mit allen System-Frameworks in iOS 7 und Mavericks verwenden. Module sind eine Verpackung des Framework-Executable und seiner Header und gelten als sicherer und effizienter als #import.

Einer der großen Vorteile bei der Verwendung von @import ist, dass Sie das Framework nicht in den Projekteinstellungen hinzufügen müssen, es geschieht automatisch. Das bedeutet, dass Sie den Schritt überspringen können, bei dem Sie auf die Plus-Schaltfläche klicken und nach dem Framework suchen (goldene Werkzeugkiste), es dann in die Gruppe "Frameworks" verschieben. Dies wird vielen Entwicklern die kryptischen "Linkerfehler"-Meldungen ersparen.

Sie müssen tatsächlich nicht das Schlüsselwort @import verwenden. Wenn Sie sich für die Verwendung von Modulen entscheiden, werden alle #import und #include-Direktiven automatisch auf @import abgebildet. Das bedeutet, dass Sie Ihren Quellcode (oder den Quellcode von Bibliotheken, die Sie aus anderen Quellen herunterladen) nicht ändern müssen. Angeblich verbessert die Verwendung von Modulen auch die Build-Performance, insbesondere wenn Sie PCHs nicht gut verwendet haben oder wenn Ihr Projekt viele kleine Quelldateien hat.

Module sind bereits für die meisten Apple-Frameworks (UIKit, MapKit, GameKit, usw.) vorinstalliert. Sie können sie auch für von Ihnen erstellte Frameworks verwenden: Sie werden automatisch erstellt, wenn Sie ein Swift-Framework in Xcode erstellen, und Sie können auch manuell eine ".modulemap"-Datei für ein beliebiges Apple- oder Drittanbieter-Library erstellen.

Sie können die Code-Vervollständigung verwenden, um die Liste der verfügbaren Frameworks einzusehen:

Bildbeschreibung hier eingeben

Module sind standardmäßig in neuen Projekten in Xcode 5 aktiviert. Um sie in einem älteren Projekt zu aktivieren, gehen Sie in Ihre Projektparameter, suchen Sie nach "Module" und setzen Sie "Module aktivieren" auf "JA" ein. Auch "Frameworks verknüpfen" sollte "JA" sein:

Sie müssen Xcode 5 und das iOS 7- oder Mavericks-SDK verwenden, aber Sie können immer noch für ältere Betriebssysteme veröffentlichen (z.B. iOS 4.3 oder ähnliches). Module ändern nicht, wie Ihr Code erstellt wird oder irgendeinen Teil des Quellcodes.


Aus den WWDC-Folien:

  • Imports vollständige semantische Beschreibung eines Frameworks
  • Muss die Header nicht analysieren
  • Bessere Möglichkeit, eine Framework-Schnittstelle zu importieren
  • Lädt die binäre Darstellung
  • Flexibler als vorkompilierte Header
  • Unempfindlich gegenüber lokalen Makrodefinitionen (z.B. #define readonly 0x01)
  • Standardmäßig für neue Projekte aktiviert

Um Module explizit zu verwenden:

Ersetzen Sie #import durch @import Cocoa;

Sie können auch nur einen Header mit dieser Notation importieren:

@import iAd.ADBannerView;

Die Submodule vervollständigen sich für Sie in Xcode.

51voto

hbk Punkte 10324

Schöne Antwort finden Sie im Buch Learning Cocoa with Objective-C (ISBN: 978-1-491-90139-7)

Module sind ein neues Mittel, um Dateien und Bibliotheken in Ihre Projekte einzuschließen und zu verknüpfen. Um zu verstehen, wie Module funktionieren und welche Vorteile sie haben, ist es wichtig, einen Blick in die Geschichte von Objective-C und das #import Statement zu werfen. Wenn Sie eine Datei für die Verwendung einbeziehen möchten, haben Sie in der Regel etwas Code, der wie folgt aussieht:

#import "someFile.h"

Oder im Falle von Frameworks:

#import 

Weil Objective-C eine Erweiterung der C-Programmiersprache ist, ist das #import Statement eine kleine Verfeinerung des #include Statements in C. Das #include Statement ist sehr einfach; es kopiert alles, was es in der inkludierten Datei findet, während der Kompilierung in Ihren Code. Dies kann manchmal zu erheblichen Problemen führen. Beispielsweise, stellen Sie sich vor, Sie haben zwei Header-Dateien: SomeFileA.h und SomeFileB.h; SomeFileA.h inkludiert SomeFileB.h, und SomeFileB.h inkludiert SomeFileA.h. Dies erzeugt eine Schleife und kann den Compiler verwirren. Um damit umzugehen, müssen C-Programmierer Schutzvorrichtungen gegen dieses Art von Ereignis schreiben.

Bei Verwendung von #import müssen Sie sich keine Sorgen um dieses Problem machen oder Schutzvorrichtungen schreiben, um es zu vermeiden. Allerdings ist #import immer noch nur eine glorifizierte Kopier- und Einfügeaktion, die zu langsamer Kompilierungszeit und einer Vielzahl anderer kleinerer, aber dennoch sehr gefährlicher Probleme führt (wie etwa eine inkludierte Datei, die etwas überschreibt, was Sie anderswo in Ihrem eigenen Code deklariert haben.)

Module sind ein Versuch, dieses Problem zu umgehen. Sie sind nicht länger eine Kopier- und Einfügeaktion in den Quellcode, sondern eine serialisierte Darstellung der inkludierten Dateien, die nur dort und dann in Ihren Quellcode importiert werden können, wo sie benötigt werden. Durch die Verwendung von Modulen wird der Code in der Regel schneller kompiliert und sicherer sein als die Verwendung von #include oder #import.

Zurück zum vorherigen Beispiel des Imports eines Frameworks:

#import 

Um diese Bibliothek als Modul zu importieren, würde der Code geändert werden zu:

@import SomeLibrary;

Dies hat den zusätzlichen Vorteil, dass Xcode automatisch das SomeLibrary Framework in das Projekt einbindet. Module ermöglichen es auch, nur die Komponenten, die Sie wirklich in Ihr Projekt einbeziehen möchten. Wenn Sie beispielsweise das AwesomeObject-Modul im AwesomeLibrary-Framework verwenden möchten, müssten Sie normalerweise alles importieren, nur um das eine Stück zu verwenden. Durch die Verwendung von Modulen können Sie jedoch nur das spezifische Objekt importieren, das Sie verwenden möchten:

@import AwesomeLibrary.AwesomeObject;

Für alle neuen Projekte, die in Xcode 5 erstellt wurden, sind Module standardmäßig aktiviert. Wenn Sie Module in älteren Projekten verwenden möchten (und das sollten Sie wirklich), müssen sie in den Build-Einstellungen des Projekts aktiviert werden. Sobald Sie das getan haben, können Sie sowohl #import als auch @import Statements in Ihrem Code verwenden, ohne sich Gedanken machen zu müssen.

7voto

yoAlex5 Punkte 20661

@import Module(ObjC) oder semantisches Import

anstelle des üblichen Moduls mit

//als Beispiel
#include 
#import 

Geschichte:

[#include -> #import] -> [Vorkompilierte Header .pch] -> @import Module(ObjC); -> [import Module(Swift)]

Es ist ein Teil von LLVM-Modulen

@import ; Deklaration sagt dem Compiler, ein vorkompiliertes Binärmodul zu laden (statt zu kompilieren), was die Build-Zeit verkürzt. Früher kompilierte der Compiler die Abhängigkeit jedes Mal, wenn er darauf traf, aber jetzt muss sie im Voraus kompiliert und nur geladen werden

//früher
stoßen auf Abhängigkeit -> Abhängigkeit kompilieren
stoßen auf Abhängigkeit -> Abhängigkeit kompilieren

//@import
kompiliere Abhängigkeit 
    stoßen auf Abhängigkeit -> geladenes Binärmodul laden
    stoßen auf Abhängigkeit -> geladenes Binärmodul laden

[Modulmap] - Brücke zwischen Modul und Headern

Xcode

Module aktivieren (C und Objective-C) (CLANG_ENABLE_MODULES) - CLANG #include, #import-Direktiven werden automatisch in @import umgewandelt, was alle Vorteile bringt. Modulemap ermöglicht dies nahtlos, da es eine Abbildung zwischen Headern und Untermodulen enthält

-fmodules übergeben

#include, #import -> @import

Frameworks automatisch verknüpfen (CLANG_MODULES_AUTOLINK) - aktiviert automatisches Verknüpfen von System-Modulen. Erfordert aktiviertes CLANG_ENABLE_MODULES. Das automatische Verknüpfen ermöglicht das Weitergeben von -framework basierend auf #import, @import(Objective-C), import(Swift)

Wenn NICHT - gibt -fno-autolink Flag weiter

CLANG_ENABLE_MODULES == NEIN und CLANG_MODULES_AUTOLINK == NEIN

Wenn Sie das System(#import ) Linking manuell (anstelle von automatischem Linking) behandeln möchten, haben Sie zwei Varianten:

  1. Abhängigkeit in Allgemein -> Frameworks und Bibliotheken oder Frameworks, Bibliotheken und eingebettete Inhalte hinzufügen

  2. Build-Einstellungen -> Andere Linkerflags (OTHER_LDFLAGS) -> -framework

Es wird ein nächster Fehler geworfen, wenn:

Nicht definierbares Symbol: _OBJC_CLASS_$_UIView

Nicht definierbare Symbole für Architektur x86_64:
  "_OBJC_CLASS_$_UIView", referenziert von:
      objc-class-ref in ClassB.o
ld: Symbol(e) für Architektur x86_64 nicht gefunden
clang: Fehler: Linker-Befehl fehlgeschlagen mit Exit-Code 1
  • CLANG_ENABLE_MODULES ist deaktiviert
  • CLANG_MODULES_AUTOLINK ist deaktiviert und kein manuelles Verknüpfen

Reverse Engineering

otool -l  
//-l gibt die Ladebefehle aus
//finde LC_LINKER_OPTION
//cmd LC_LINKER_OPTION

4voto

RyanTCB Punkte 6468

Es funktioniert derzeit nur für die integrierten System-Frameworks. Wenn Sie #import verwenden wie Apple immer noch das UIKit-Framework im App-Delegierten importieren, wird es ersetzt (wenn Module aktiviert sind und es als System-Framework erkannt wird) und der Compiler wird es neu zu einem Modulimport zuordnen und nicht zu einem Import der Headerdateien sowieso. Also wird das #import zu verlassen sowieso genauso wie es konvertiert wird zu einem Modulimport, wenn möglich

2voto

loretoparisi Punkte 14321

Es scheint, dass seit XCode 7.x viele Warnungen auftreten, wenn das Clang-Modul mit CLANG_ENABLE_MODULES aktiviert ist

Schauen Sie sich Viele Warnungen beim Erstellen von Xcode 7 mit Drittanbieterbibliotheken an

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X