718 Stimmen

@class vs. #import

Nach meinem Verständnis sollte man eine Forward-Class-Deklaration für den Fall verwenden, dass ClassA einen ClassB-Header einschließen muss und ClassB einen ClassA-Header einschließen muss, um zirkuläre Einschlüsse zu vermeiden. Ich verstehe auch, dass eine #import ist eine einfache ifndef so dass ein Include nur einmal vorkommt.

Meine Frage lautet wie folgt: Wann verwendet man #import und wann verwendet man @class ? Manchmal, wenn ich eine @class Deklaration sehe ich eine allgemeine Compiler-Warnung wie die folgende:

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

Ich würde das wirklich gerne verstehen, im Gegensatz zum einfachen Entfernen der @class Vorwärts-Erklärung und das Auslösen einer #import ein, um die Warnungen des Compilers zum Schweigen zu bringen.

3voto

Wenn ich entwickle, habe ich nur drei Dinge im Kopf, die mir nie Probleme bereiten.

  1. Superklassen importieren
  2. Elternklassen importieren (wenn Sie Kinder und Eltern haben)
  3. Importieren von Klassen außerhalb Ihres Projekts (wie in Frameworks und Bibliotheken)

Für alle anderen Klassen (Unterklassen und untergeordnete Klassen in meinem Projekt selbst) deklariere ich sie über forward-class.

3voto

IluTov Punkte 6635

Wenn Sie versuchen, eine Variable oder eine Eigenschaft in Ihrer Header-Datei zu deklarieren, die Sie noch nicht importiert haben, werden Sie einen Fehler erhalten, der besagt, dass der Compiler diese Klasse nicht kennt.

Ihr erster Gedanke ist wahrscheinlich #import es.
Dies kann in einigen Fällen zu Problemen führen.

Zum Beispiel, wenn Sie eine Reihe von C-Methoden in der Header-Datei implementieren, oder Structs, oder etwas ähnliches, weil sie nicht mehrfach importiert werden sollten.

Daher können Sie dem Compiler mit @class :

Ich weiß, dass Sie diese Klasse nicht kennen, aber es gibt sie. Sie wird an anderer Stelle importiert oder implementiert werden

Es sagt dem Compiler im Grunde, dass er die Klappe halten und kompilieren soll, obwohl er nicht sicher ist, ob diese Klasse jemals implementiert werden wird.

In der Regel werden Sie Folgendes verwenden #import im .m y @class im .h Dateien.

0voto

karthick Punkte 1

Forward-Deklaration nur um zu verhindern, dass der Compiler einen Fehler anzeigt.

weiß der Compiler, dass es eine Klasse mit dem Namen gibt, den Sie in Ihrer Header-Datei zum Deklarieren verwendet haben.

0voto

Deepak G M Punkte 1620

Der Compiler wird sich nur beschweren, wenn Sie die Klasse so verwenden, dass der Compiler ihre Implementierung kennen muss.

Ex:

  1. Dies könnte z. B. der Fall sein, wenn Sie Ihre Klasse davon ableiten wollen oder
  2. Wenn Sie ein Objekt dieser Klasse als Mitgliedsvariable haben werden (was allerdings selten vorkommt).

Es wird sich nicht beschweren, wenn Sie es nur als Zeiger verwenden. Natürlich müssen Sie es in der Implementierungsdatei #importieren (wenn Sie ein Objekt dieser Klasse instanziieren), da es den Klasseninhalt kennen muss, um ein Objekt zu instanziieren.

HINWEIS: #import ist nicht dasselbe wie #include. Das bedeutet, dass es nichts gibt, was als zirkulärer Import bezeichnet wird. import ist eine Art Aufforderung an den Compiler, in einer bestimmten Datei nach bestimmten Informationen zu suchen. Wenn diese Informationen bereits vorhanden sind, ignoriert der Compiler sie.

Versuchen Sie es einfach, importieren Sie A.h in B.h und B.h in A.h. Es wird keine Probleme oder Beschwerden geben und es wird auch gut funktionieren.

Wann ist @class zu verwenden?

Sie verwenden @class nur, wenn Sie gar keine Kopfzeile in Ihre Kopfzeile importieren wollen. Dies könnte ein Fall sein, in dem Sie nicht einmal wissen wollen, was die Klasse sein wird. Fälle, in denen Sie vielleicht noch nicht einmal einen Header für diese Klasse haben.

Ein Beispiel hierfür könnte sein, dass Sie zwei Bibliotheken schreiben. Eine Klasse, nennen wir sie A, existiert in einer Bibliothek. Diese Bibliothek enthält einen Header aus der zweiten Bibliothek. Dieser Header könnte einen Zeiger auf A haben, muss ihn aber nicht unbedingt verwenden. Wenn die Bibliothek 1 noch nicht verfügbar ist, wird die Bibliothek B nicht blockiert, wenn Sie @class verwenden. Wenn Sie jedoch A.h importieren wollen, wird der Fortschritt von Bibliothek 2 blockiert.

0voto

Sujananth Punkte 585

Dies ist ein Beispielszenario, in dem wir @class benötigen.

Wenn Sie ein Protokoll in einer Header-Datei erstellen möchten, das einen Parameter mit einem Datentyp der gleichen Klasse hat, können Sie @class verwenden. Bitte denken Sie daran, dass Sie Protokolle auch separat deklarieren können, dies ist nur ein Beispiel.

// DroneSearchField.h

#import <UIKit/UIKit.h>
@class DroneSearchField;
@protocol DroneSearchFieldDelegate<UITextFieldDelegate>
@optional
- (void)DroneTextFieldButtonClicked:(DroneSearchField *)textField;
@end
@interface DroneSearchField : UITextField
@end

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