Come posso dichiarare un array come costante in Objective-c?

Il seguente codice mi dà errori:

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

L’errore che ottengo è
initializer element is not constant

O se togli l’indicatore del puntatore (*) ottengo:
statically allocated instance of Objective-C class 'NSArray'

In breve, non puoi. Gli oggetti Objective-C sono, ad eccezione delle costanti NSString, creati solo in runtime e, quindi, non è ansible utilizzare un’espressione per inizializzarli.

Ci sono una manciata di approcci.

(1) Dichiarare NSArray *testArray senza la parola chiave const e quindi disporre di un bit di codice che imposta il valore che viene richiamato molto presto durante il ciclo di vita dell’applicazione.

(2) Dichiarare un metodo di class conveniente che restituisce l’array, quindi utilizzare un static NSArray *myArray all’interno di tale metodo e trattarlo come un singleton (cercare SO per “objective-c singleton” per circa un milione di risposte su come istanziare).

Un po ‘tardi per la festa, ma dato che non stai cambiando i valori nel corso del programma, se ti occupavi solo di stringhe, puoi fare quanto segue dichiarando il tuo array usando un array C :

 extern NSString * const MY_CONSTANT_STRING_ARRAY[]; 

nel tuo file constants.h , e poi nelle tue constants.m potresti aggiungere oggetti ad esso in questo modo:

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

Quindi per accedere a un membro, puoi fare un ciclo for come in questo modo con un operatore C sizeof() :

Ovviamente si tratta di un array C e non di un NSArray pertanto non è ansible utilizzare tutti i metodi divertenti come objectAtIndex: modo è ansible creare una funzione di supporto da qualche parte nel programma che objectAtIndex: loop su tutte le stringhe utilizzando il metodo I delineato sopra e restituisce un NSArray (o NSMutableArray anche). Ma, se tu stavi facendo quello che sono e solo bisogno di una serie costante di valori NSString da utilizzare nel tuo programma, questo metodo funziona al meglio.

Facendolo in questo modo incapsula tutti i tuoi contendenti dell’array di stringhe in constants.h , ed è ancora disponibile in tutto il programma aggiungendo constants.h nel tuo file .pch invece di creare un singleton solo per questa matrice di valori o impostando l’array con un piccolo codice, che sorta sconfigge lo scopo di un file di constants perché rimuove le costanti effettive dal file delle constants .

MODIFICA per @ Commento di JesseGumpo :

Poiché potrebbero esserci problemi con l’utilizzo di sizeof() per determinare la dimensione dell’array, una semplice soluzione è dichiarare la dimensione dell’array nel file delle costanti in questo modo:

 //.h extern int SIZE_OF_MY_CONSTANTS_ARRAY; ///.m int SIZE_OF_MY_CONSTANTS_ARRAY = 2; 

E quindi per accedere ai membri in un ciclo for puoi farlo in questo modo:

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

Sì, questo non cattura dynamicmente la dimensione dell'array, ma se stai dichiarando una matrice in un file di costanti già conosci la dimensione di quell'array dall'inizio, quindi anche se aggiunge altre due righe di codice, svolge ancora il compito di avere una matrice in un file di costanti.

Se qualcuno ha altri suggerimenti o potrebbe conoscere qualche altro trucchetto, per favore lascia un commento qui sotto!

Ecco una macro per farlo in una riga per un’istanza statica in un ambito del metodo.

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

Usa l’esempio

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

È abbastanza facile:

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

messo prima dell’implementazione e senza punto e virgola.

spero che sia d’aiuto.

Per quanto mi riguarda, è più comodo usare la seguente implementazione per una serie di costanti

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

Ho un file di intestazione chiamato “Constants.h” e all’interno dei prossimi array costanti:

 #define arrayOfStrings @[@"1", @"2", @"3", @"4"] #define arraysOfIds @[@(1), @(2), @(3), @(4)] 

Fondamentalmente, quando si chiama arrayOfStrings nel proprio codice, viene sostituito con @ [@ “1”, @ “2”, @ “3”, @ “4”] e la stessa cosa con arraysOfIds.