2013-02-16 11 views
7

Ich verstehe, dass das Platzieren des Worts extern vor einer Variablendeklaration in einer Headerdatei das Vorhandensein einer globalen statischen Variable deklariert, ohne sie zu initialisieren. Ich verstehe auch, dass, wenn ich die Datei importiere, die die extern Variablen enthält, ich sie ohne einen Klassen-/Dateinamen verweisen kann. Aber wo definiert man sie und ihre Werte?Äquivalent von öffentlichen statischen Endvariablen

Was ich versuche, ist eine Klasse von Konstanten mit globalen Konstanten, die ich im Code einer iOS-Anwendung verwenden möchte.

Setzt man sie so in die Schnittstelle ein?

Example.h

#import <Foundation/Foundation.h> 
@interface Constraints : NSObject 
{ 

extern NSString * const PREFS_NAME; 

} 

Oder hat eine Put dann außerhalb der Schnittstelle wie diese

Example.h

#import <Foundation/Foundation.h> 

extern NSString * const PREFS_NAME;  

@interface Constraints : NSObject 
{ 

} 

dann bei der Umsetzung .m-Datei Wie würde man die externen Werte initialisieren?

Im Implementierungsbereich so?

Example.m

#import "Constraints.h" 

@implementation Constraints 

/**PRefecences name for the application**/ 
const NSString * PREFS_NAME = @"MyApp_Prefs"; 

@end 

Oder sie so außerhalb des Implementierungsbereich initialisiere:

Example.m

#import "Constraints.h" 

/**PRefecences name for the application**/ 
const NSString * PREFS_NAME = @"MyApp_Prefs"; 

@implementation Constraints 

@end 

Oder stelle ich ihnen ihre Anfangswerte in einem Konstruktor? oder irgendeine willkürliche statische Methode mit + davor, d.h. +(void) setAppConstraints;

Ich habe mehrere Kombinationen ausprobiert, aber immer auf Fehler stoßen, wie "Neudefinition von 'xVariable' mit einem anderen Typ". Oder etwas über "extern hat keine Initialisierungsschnittstelle" (oder so etwas, das ich vergesse). Also möchte ich wissen, wie man sie richtig deklariert und initialisiert, um die gleiche Rolle wie public static final Variablen in Java zu bilden.

Auch was sind die Grenzen des Befehls extern? Ich weiß, ich kann extern ein NSInteger oder NSString, aber was ist mit NSArray?

Ich stelle diese Frage, weil es zu viele irreführende oder unvollständige Informationen bezüglich der Verwendung von extern in Objective-C zu geben scheint. Viele der Antworten scheinen spekulativ zu sein. Ich hoffe, dass diese Frage nicht nur für mich eine gute Ressource ist, sondern weitere ähnliche Fragen zu den Grundlagen von extern zu begrenzen.

+0

möglich Duplikat von [Verwendung von 'extern' Schlüsselwort beim Definieren der Variablen] (http://stackoverflow.com/questions/7606909/use-of-extern-keyword-while-defining-the-variable) –

+0

Wenn Sie möchte "eine Klasse von Konstanten erstellen", die nichts mit globalen Variablen zu tun hat, weil sie keiner Klasse angehören. Dafür brauchst du Ivars. –

+0

@Josh Cashwell möglich ist eine ähnliche Frage. Aber wie ich in meinem Fragetext gesagt habe, waren alle Antworten, die ich zu S/O fand, unvollständig oder hinterließen mehr Fragen als Antworten. –

Antwort

11

Sie definieren seinen Wert in der Datei, in der er deklariert ist, in Ihrem Fall ist Example.m; Sie können immer noch diese Variable neu zuweisen, so dass die Erklärung in Example.h würde wie folgt aussehen: auf diese Variable

extern NSString * PREFS_NAME; 

diese Weise wird jede Datei, die importiert Example.h Zugriff hat. Das Äquivalent des öffentlichen statischen Finales in Objective-C ist const. Wenn Sie auch möchten, dass es öffentlich ist, sollten Sie es als Klasseninstanzvariable definieren, aber in diesem Fall brauchen Sie es nicht, weil es überall zugänglich ist. Also in diesem Fall wäre es:

// .m file 
NSString* const PREFS_NAME = @"MyApp_Prefs"; 
// .h file 
extern NSString* const PREFS_NAME; 

Beachten Sie auch, dass const NSString * unterscheidet sich von NSString * const. Letzteres ist ein Const-Zeiger auf NSString. Ersteres hat keinen Sinn, auch wenn es eine korrekte Syntax ist. In Objective-C beeinflusst das const-Qualifikationsmerkmal keine Objekte, stattdessen gibt es veränderbare und unveränderliche Klassen. Es hätte Sinn in C++, was bedeutet, dass Sie nur konstante Methoden für die Instanz verwenden können.

+0

Sehr nützlicher Beitrag danke. –

+0

Wäre das "NSString * const PREFS_NAME = @" MyApp_Prefs ";" innerhalb oder außerhalb der @ Implementierung und @end Paarung sein? –

+1

Draußen, weil es kein Ivar ist. –

3

extern wird verwendet, um dem Compiler mitzuteilen, dass Sie eine Variable oder eine Funktion verwenden, die in einer anderen Kompilierungseinheit definiert ist.

Wenn Sie sagen extern const NSString *PREFS_NAME, sagen Sie "Ersetzen Sie alle Referenzen in dieser Kompilierungseinheit zu PREFS_NAME für die Variable PREFS_NAME, wie es in einer anderen Datei definiert ist."Wenn Sie also versuchen, PREFS_NAME in Ihrer .m anzuordnen, versuchen Sie nur, eine Variable zuzuweisen, die zwar einen Namen hat, aber nicht existiert. Das Deklarieren einer Variablen extern ist nur eine Deklaration einer Variablen oder Funktion, keine Definition dieser Variablen oder Funktion. Es lässt den Compiler wissen, dass der Name verwendet wird, und dass der Linker kümmert sich um was damit zu tun, aber auch wenn Sie einen Typ hier angeben, Es wird nicht tatsächlich Speicherplatz für die Variable reserviert, es wird erwartet, dass der Speicherplatz in der Kompilierungseinheit reserviert wird, die die Variable tatsächlich definiert.

Sie kompilieren drei oder vier verschiedene Quellcodedateien zusammen, von denen drei deklarieren können :

extern int buffer[];

Und man kann

int buffer[BUFSIZE];

im Rahmen seiner globalen Reichweite und die Aufgabe des Linkers erklären ist, die drei erklärt Verweise auf extern buffer auf die vierte tatsächliche Definition des Puffers zu lösen.

extern ist zu C-Variablen und Funktionen viel wie @class Objective-C-Klassen ist, ist es eine Vorwärts-Deklaration, ein Versprechen an den Compiler, die Sie müssen nicht ausflippen, wenn Sie einen Namen, die hier nicht definiert ist, weil Der Linker wird alle Fragen beantworten, die Sie noch haben.

+0

Das ist soweit ich es verstehe. Wie initialisiere ich eine externe Variable, so dass das ganze Projekt sie und ihren Wert sehen kann? –

+0

Sie können es in der .h-Datei initialisieren, das erste Mal, wenn Sie die Variable 'extern' deklarieren, oder Sie ordnen sie im globalen Bereich Ihrer .m-Datei zu. Sie würden NICHT das Schlüsselwort 'extern' verwenden, wenn Sie initialisieren, und Sie würden NICHT das Schlüsselwort' static' verwenden. 'static' ist das Gegenteil von' extern', es beschränkt die Definition der Variablen auf die Kompilierungseinheit und erlaubt es anderen nicht, darauf Bezug zu nehmen. – iluvcapra

+0

PS Die meisten Leute, die das in Obj-C machen, würden einfach '#define PREFS_NAME @" MyApp_Prefs "' ... Wir alle laufen kreischend aus dem Gedanken an 'public static final' und was es bedeuten könnte :) – iluvcapra