Meine Anfrage ist dies. Wann benutzt man #import und wann benutzt man @class?
Einfache Antwort: Sie #import
oder #include
wenn es eine physische Abhängigkeit gibt. Andernfalls verwenden Sie Vorwärtsdeklarationen ( @class MONClass
, struct MONStruct
, @protocol MONProtocol
).
Hier sind einige häufige Beispiele für körperliche Abhängigkeit:
- Beliebiger C- oder C ++ - Wert (ein Zeiger oder eine Referenz ist keine physische Abhängigkeit). Wenn Sie eine
CGPoint
als ivar oder Eigenschaft haben, muss der Compiler die Deklaration von sehen CGPoint
.
- Deine Superklasse.
- Eine Methode, die Sie verwenden.
Wenn ich eine @ class-Deklaration verwende, wird manchmal eine allgemeine Compiler-Warnung angezeigt, z. B. die folgende: "Warnung: Der Empfänger 'FooController' ist eine Forward-Klasse, und die entsprechende @ -Interface ist möglicherweise nicht vorhanden."
Der Compiler ist in dieser Hinsicht eigentlich sehr nachsichtig. Es werden Hinweise (wie oben) gelöscht, aber Sie können Ihren Stapel leicht in den Papierkorb werfen, wenn Sie sie ignorieren und nicht #import
richtig. Obwohl dies der Fall sein sollte (IMO), erzwingt der Compiler dies nicht. In ARC ist der Compiler strenger, da er für die Referenzzählung verantwortlich ist. Der Compiler greift auf eine Standardeinstellung zurück, wenn er auf eine unbekannte Methode stößt, die Sie aufrufen. Jeder Rückgabewert und Parameter wird angenommen id
. Daher sollten Sie jede Warnung aus Ihren Codebasen entfernen, da dies als physische Abhängigkeit betrachtet werden sollte. Dies ist analog zum Aufrufen einer C-Funktion, die nicht deklariert ist. Mit C werden Parameter angenommen int
.
Der Grund, warum Sie Forward-Deklarationen bevorzugen, besteht darin, dass Sie Ihre Erstellungszeiten um Faktoren reduzieren können, da nur eine minimale Abhängigkeit besteht. Bei Vorwärtsdeklarationen sieht der Compiler, dass es einen Namen gibt, und kann das Programm korrekt analysieren und kompilieren, ohne die Klassendeklaration oder alle ihre Abhängigkeiten zu sehen, wenn keine physische Abhängigkeit besteht. Saubere Builds benötigen weniger Zeit. Inkrementelle Builds benötigen weniger Zeit. Sicher, Sie werden am Ende etwas mehr Zeit damit verbringen, sicherzustellen, dass alle benötigten Header für jede Übersetzung sichtbar sind. Dies zahlt sich jedoch in kürzeren Erstellungszeiten schnell aus (vorausgesetzt, Ihr Projekt ist nicht winzig).
Wenn Sie #import
oder #include
stattdessen verwenden, werfen Sie viel mehr Arbeit auf den Compiler als nötig. Sie führen auch komplexe Header-Abhängigkeiten ein. Sie können dies mit einem Brute-Force-Algorithmus vergleichen. Wenn Sie dies #import
tun, ziehen Sie Tonnen unnötiger Informationen ein, die viel Speicher, Festplatten-E / A und CPU erfordern, um die Quellen zu analysieren und zu kompilieren.
ObjC ist in Bezug auf die Abhängigkeit nahezu ideal für eine C-basierte Sprache, da NSObject
Typen niemals Werte sind - NSObject
Typen sind immer Zeiger mit Referenzzählung. Sie können also mit unglaublich schnellen Kompilierungszeiten davonkommen, wenn Sie die Abhängigkeiten Ihres Programms entsprechend strukturieren und wenn möglich weiterleiten, da nur sehr wenig physische Abhängigkeit erforderlich ist. Sie können auch Eigenschaften in den Klassenerweiterungen deklarieren, um die Abhängigkeit weiter zu minimieren. Das ist ein großer Bonus für große Systeme - Sie würden den Unterschied kennen, den es macht, wenn Sie jemals eine große C ++ - Codebasis entwickelt haben.
Daher empfehle ich, wenn möglich vorwärts zu verwenden und dann #import
dorthin , wo physische Abhängigkeit besteht. Wenn Sie die eine oder andere Warnung sehen, die physische Abhängigkeit impliziert, beheben Sie sie alle. Das Update befindet sich #import
in Ihrer Implementierungsdatei.
Während Sie Bibliotheken erstellen, werden Sie wahrscheinlich einige Schnittstellen als Gruppe klassifizieren. In diesem Fall würden Sie die #import
Bibliothek verwenden, in der physische Abhängigkeit eingeführt wird (z #import <AppKit/AppKit.h>
. B. ). Dies kann zu Abhängigkeiten führen, aber die Bibliotheksverwalter können häufig die physischen Abhängigkeiten für Sie nach Bedarf behandeln. Wenn sie eine Funktion einführen, können sie die Auswirkungen auf Ihre Builds minimieren.