2010-12-04 12 views
4

Ich habe über Konstanten gesucht und ich verstehe nicht wirklich, was anders an ihnen anders als sie nicht programmgesteuert geändert werden können.Erklärung der Konstanten

extern NSString * const MyConstant; 

Mit dieser Linie, was genau extern bedeutet und was genau bedeutet die const bedeuten?

Antwort

19

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.

+0

Prost zu denen, die es brechen. Brechen Sie es auf. –

-1

Extern bedeutet, dass die Variable außerhalb der Quelldatei festgelegt wird, in der sie deklariert wurde. Es wird empfohlen, das OBJC_EXPORT-Flag anstelle von extern zu verwenden.

Const bedeutet, dass die Variable nach dem Einstellen nicht geändert werden kann. Sie können jedoch einige Zeiger misdirection verwenden, wie unten dargestellt:

NSString **var = (NSString **)&MyConstant; 
*var = @"I changed it!"; 

, die tatsächlich ermöglicht es Ihnen, es zu ändern, wenn Sie benötigen (zum Beispiel in Ihren Klassen +initialize Methode).

+0

Der erste Absatz ist sinnvoll. Der Rest ist für diese Frage nicht relevant (und macht keinen Sinn). – bbum

2
extern NSString * const MyConstant; 

Sie sehen dies in den Header-Dateien. Es teilt dem Compiler mit, dass die Variable MyConstant existiert und in Ihren Implementierungsdateien verwendet werden kann.

Wahrscheinlicher als nicht, die Variable wird so etwas wie:

NSString * const MyConstant = @"foo"; 

Der Wert kann nicht verändert werden. Wenn Sie eine globale Variable ändern möchten, löschen Sie die const aus der Deklaration.

+0

Sie sollten selten, wenn überhaupt, 'extern' in Header-Dateien sehen. Das Schlüsselwort "extern" existiert, damit der Linker Symbole auflösen kann, die in Übersetzungseinheiten verwendet werden. Keine Notwendigkeit, 'extern' zu verwenden, wenn das Symbol in einer Header-Datei deklariert ist; Importieren Sie einfach die Header-Datei. Und es ist nicht nötig, 'extern' zu verwenden, um ein Symbol in eine Header-Datei zu importieren, da Globals nicht Teil der Schnittstelle für eine Klasse sind. –