Sie werden hier zwei Fragen gestellt: eine über Konstanten und eine über extern. Die beiden sind nicht unbedingt verwandt.
Zuerst const: Konstanten gibt es nicht viel mehr als, wie Sie sagten, sie können nicht programmgesteuert geändert werden. Verschiedene Dinge können jedoch konstant sein, abhängig davon, wie Sie sie deklarieren. Zum Beispiel, in Ihrem Beispiel:
NSString * const MyConstant = @"foo";
Sie haben einen konstanten Zeiger auf ein nicht konstantes NSString Objekt deklarieren; Das Schlüsselwort const
befindet sich rechts neben dem Stern. Es bezieht sich also auf den Zeiger. Somit folgt aus:
MyConstant = @"bar";
würde in einem Compiler-Fehler führen, da es versucht, MyConstant
neu zuweisen zu einem anderen NSString zu zeigen.
Wenn das Schlüsselwort const
links vom Stern wäre, würde es sich auf das Objekt beziehen, auf das der Zeiger verweist (in diesem Fall die zugrunde liegende NSString-Struktur). Dies ist wahrscheinlich nicht das, was Sie in Objective C. die meiste Zeit wollen Beachten Sie, dass die Position des const
Schlüsselwort in Bezug auf die Typkennung spielt keine Rolle, so dass dies:
const NSString *MyConstant = @"foo";
und diese:
NSString const *MyConstant = @"foo";
bedeuten die gleiche Sache.Sie können auch erklären rechtlich sowohl den Zeiger und den referenzierten Wert const, für maximale Konstantheit:
const NSString * const MyConstant = @"foo";
Zweitens extern: extern
einfach können Sie eine Variable in einer Übersetzungseinheit erklären, und lassen Sie den Compiler wissen, dass Sie haben diese Variable in einer separaten Kompilierungseinheit definiert. Sie würden dies normalerweise nur für globale Werte und Konstanten verwenden.
Sie können sich eine Kompilierungseinheit als eine einzelne .m
Datei vorstellen, sowie alle darin enthaltenen .h
Dateien. Zur Erstellungszeit kompiliert der Compiler jede .m-Datei in eine separate .o
-Datei, und dann verknüpft der Linker sie alle zu einer einzigen Binärdatei. Normalerweise ist die Art und Weise, wie eine Kompilierungseinheit über Kennungen (z. B. einen Klassennamen) bekannt ist, die in einer anderen Kompilierungseinheit deklariert sind, durch Importieren einer Header-Datei. Aber im Fall von Globals sind sie oft nicht Teil der öffentlichen Schnittstelle einer Klasse, daher werden sie häufig in einer Datei .m
deklariert und definiert.
Wenn Kompilierungseinheit A erklärt ein global in einer .m
Datei:
#import "A.h"
NSString *someGlobalValue;
und Übersetzungseinheit B will, dass die globale verwenden:
#import "B.h"
extern NSString *someGlobalValue;
@implementation B
- (void)someFunc {
NSString *localValue = [self getSomeValue];
if (localValue isEqualToString:someGlobalValue]) {
...
}
}
Einheit B den Compiler irgendwie zu sagen hat zu verwenden Die von Unit A deklarierte Variable. Sie kann die .m
-Datei, in der die Deklaration auftritt, nicht importieren. Daher verwendet sie extern
, um dem Compiler mitzuteilen, dass die Variable an anderer Stelle existiert.
Beachten Sie, dass, wenn die Einheit A und Einheit B beid haben diese Linie auf der obersten Ebene der Datei:
NSString *someGlobalValue;
dann haben Sie zwei Kompilierungseinheiten die gleiche globale Variable deklariert, und die Linker fehl mit einem doppelten Symbolfehler. Wenn Sie eine Variable wie diese haben wollen, die nur innerhalb einer Übersetzungseinheit vorhanden ist, und ist unsichtbar für alle anderen Übersetzungseinheiten (auch wenn sie extern
verwenden), können Sie das static
Schlüsselwort:
static NSString * const someFileLevelConstant = @"wibble";
Diese kann für Konstanten nützlich sein, die Sie in einer einzelnen Implementierungsdatei verwenden möchten, aber nicht woanders benötigen.
Prost zu denen, die es brechen. Brechen Sie es auf. –