65 Stimmen

Wie deklariere ich ein Array als eine Konstante in Objective-C?

Der folgende Code führt zu Fehlern:

//  constants.h
extern NSArray const *testArray;

//  constants.m
NSArray const *testArray = [NSArray arrayWithObjects:  @"foo", @"bar", nil];

Der Fehler, den ich erhalte, lautet
initializer element is not constant

Oder wenn ich den Zeiger-Indikator (*) wegnehme, erhalte ich:
statically allocated instance of Objective-C class 'NSArray'

71voto

bbum Punkte 161596

Kurz gesagt: Sie können es nicht. Objective-C-Objekte werden, mit Ausnahme von NSString, immer nur zur Laufzeit erstellt. Daher können Sie nicht einen Ausdruck verwenden, um sie zu initialisieren.

Es gibt eine Handvoll Ansätze.

(1) Erklären NSArray *testArray ohne die const Schlüsselwort und haben dann ein Stück Code, das den Wert einrichtet, der sehr früh im Lebenszyklus der Anwendung aufgerufen wird.

(2) Deklarieren Sie eine praktische Klassenmethode, die das Array zurückgibt, und verwenden Sie dann eine static NSArray *myArray innerhalb dieser Methode und behandeln es als ein Singleton (suchen Sie SO für "objective-c singleton" für etwa eine Zillion Antworten auf, wie zu instanziieren).

34voto

AngeloS Punkte 5358

Ich bin zwar etwas spät dran, aber da Sie die Werte im Laufe des Programms nicht ändern, könnten Sie, wenn Sie nur mit Zeichenketten arbeiten würden, folgendes tun, indem Sie Ihr Array mit einer C Array:

extern NSString * const MY_CONSTANT_STRING_ARRAY[];

in Ihrem constants.h Datei, und dann in Ihrer constants.m können Sie Objekte wie folgt hinzufügen:

NSString * const MY_CONSTANT_STRING_ARRAY[] = { @"foo", @"bar" };

Um dann auf ein Mitglied zuzugreifen, könnten Sie eine for-Schleife wie folgt ausführen mit einer C sizeof() Betreiber:

Dies ist offensichtlich eine C Array und nicht ein NSArray so dass Sie nicht alle lustigen Methoden, die damit verbunden sind, wie objectAtIndex: Sie könnten also irgendwo in Ihrem Programm eine Hilfsfunktion erstellen, die alle Zeichenketten mit der oben beschriebenen Methode durchläuft und eine NSArray (oder NSMutableArray gerade). Aber wenn Sie tun, was ich tue, und nur eine konstante Reihe von NSString Werte in Ihrem Programm zu verwenden, funktioniert diese Methode am besten.

Auf diese Weise kapseln Sie alle Inhalte Ihres String-Arrays in constants.h und ist weiterhin in Ihrem Programm verfügbar, indem Sie constants.h in Ihrem .pch Datei zu erstellen, anstatt ein Singleton nur für dieses Array von Werten zu erstellen oder das Array mit ein wenig Code zu setzen, was irgendwie den Zweck einer constants Datei, weil sie die eigentlichen Konstanten aus der constants Datei.

EDIT per Kommentar von @JesseGumpo :

Da es Probleme bei der Verwendung von sizeof() um die Größe des Arrays zu bestimmen, können Sie die Größe des Arrays einfach in Ihrer Konstanten-Datei wie folgt deklarieren:

//.h
extern int SIZE_OF_MY_CONSTANTS_ARRAY;  

///.m
int SIZE_OF_MY_CONSTANTS_ARRAY = 2;

Um dann in einer for-Schleife auf die Mitglieder zuzugreifen, können Sie wie folgt vorgehen:

for (int i=0; i < SIZE_OF_MY_CONSTANTS_ARRAY; i++) 
        NSLog(@"my constant string is: %@", MY_CONSTANT_STRING_ARRAY[i]);

Ja, damit wird die Größe des Arrays nicht dynamisch erfasst, aber wenn man ein Array in einer Konstanten-Datei deklariert, kennt man die Größe des Arrays bereits von Anfang an, so dass man zwar zwei weitere Codezeilen hinzufügt, aber dennoch die Aufgabe erfüllt, ein Array in einer Konstanten-Datei zu haben.

Wenn jemand weitere Vorschläge hat oder andere Möglichkeiten kennt C Tricks bitte unten einen Kommentar hinterlassen!

9voto

JoeM Punkte 134

Hier ist ein Makro, das dies in einer Zeile für eine statische Instanz in einem Methodenbereich erledigt.

#define STATIC_ARRAY(x, ...)   \
        static NSArray* x=nil; \
        static dispatch_once_t x##onceToken; \
        dispatch_once(&x##onceToken, ^{ x = @[ __VA_ARGS__ ]; });

Beispiel verwenden

    STATIC_ARRAY(foo, @"thing1", @"thing2", [NSObject new]);

7voto

HelmiB Punkte 12185

Es ist ziemlich einfach:

#define arrayTitle [NSArray arrayWithObjects: @"hi",@"foo",nil]

vor der Implementierung und ohne Semikolon setzen.

Ich hoffe, es hilft.

6voto

Vlad Smelov Punkte 71

Für mich ist es bequemer, die folgende Implementierung für ein Array von Konstanten zu verwenden

static NSString * kHeaderTitles [3] = {@ "ACCOUNT DETAILS", @ "SOCIAL NETWORK", @ "SETTINGS"};
static int kNumbers[3] = {1, 2, 3};

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