65 votes

Comment déclarer un tableau comme une constante dans Objective-c?

Le code suivant me donne des erreurs:

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

L'erreur que je reçois est
initializer element is not constant

Ou si je retire l'indicateur de pointeur (*), je reçois:
statically allocated instance of Objective-C class 'NSArray'

71voto

bbum Points 124887

En bref, vous ne pouvez pas. Objective-C sont les objets, à l'exception de NSString constantes, sans ne jamais créé lors de l'exécution et, par conséquent, vous ne pouvez pas utiliser une expression pour les initialiser.

Il y a une poignée d'approches.

(1) Déclarer NSArray *testArray sans const mot-clé et puis avoir un peu de code qui définit la valeur qui est appelé très tôt au cours de la vie de l'application.

(2) Déclarer une classe pratique de la méthode qui retourne un tableau, puis d'utiliser un static NSArray *myArray à l'intérieur de cette méthode et de la traiter comme un singleton (une recherche pour "objective-c singleton" pour sur un tas de réponses sur la façon d'instancier).

34voto

AngeloS Points 1555

Un peu en retard à la fête, mais puisque vous n'êtes pas à modifier les valeurs par le biais de cours du programme, si vous ne traitez avec des chaînes, vous pouvez faire ce qui suit en déclarant votre tableau à l'aide d'un C tableau:

extern NSString * const MY_CONSTANT_STRING_ARRAY[];

dans votre constants.h le fichier, puis dans votre constants.m vous pouvez ajouter des objets à elle de la sorte:

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

Ensuite, pour accéder à un membre, vous pouvez faire une boucle for comme avec un C sizeof() opérateur:

De toute évidence, cela est un C tableau et pas un NSArray si vous n'obtenez pas toutes les méthodes amusantes attaché à elle comme objectAtIndex:, de sorte que vous pouvez créer une fonction d'aide quelque part dans votre programme qui boucle sur toutes les chaînes à l'aide de la méthode que j'ai décrite ci-dessus et renvoie un NSArray (ou NSMutableArray même). Mais, si vous faites ce que je suis et juste besoin d'une constante tableau d' NSString valeurs à utiliser tout au long de votre programme, cette méthode fonctionne le mieux.

Cette façon de faire est un condensé de tous de votre tableau de chaîne de contants en constants.h, et est toujours disponible tout au long de votre programme par l'ajout d' constants.h votre .pch le fichier au lieu de créer un singleton juste pour ce tableau de valeurs ou de réglage de la matrice avec un peu de code, qui sorta de défaites le but de l' constants le fichier, car elle élimine les réelles constantes de l' constants le fichier..

L'ÉDITION par @JesseGumpo Commentaire:

Car il peut y avoir des problèmes avec l'utilisation de sizeof() pour déterminer la taille du tableau, une solution simple est de déclarer la taille du tableau dans votre fichier de constantes comme suit:

//.h
extern int SIZE_OF_MY_CONSTANTS_ARRAY;  

///.m
int SIZE_OF_MY_CONSTANTS_ARRAY = 2;

Et puis pour accéder aux membres d'une boucle for, vous pouvez le faire comme ceci:

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

Oui, ce n'est pas dynamiquement la capture de la taille de la matrice, mais si vous êtes à la déclaration d'un tableau dans un fichier de constantes, vous connaissez déjà la taille de ce tableau depuis le début, donc, même si elle ajoute deux lignes de code, il encore accomplit la tâche de créer un tableau dans un fichier de constantes.

Si quelqu'un a des suggestions ou connaître quelques autres C astuces veuillez laisser un commentaire ci-dessous!

8voto

user3412622 Points 36

Voici une macro à faire dans une ligne pour une instance statique dans une étendue de méthode.

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

Exemple d'utilisation

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

7voto

HelmiB Points 3420

vous pourriez utiliser

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

mis avant la mise en œuvre et sans point-virgule.

J'espère que ça aide.

-2voto

narco Points 36

Cela permettra d'obtenir un tableau qui ne peut pas être facilement changé (c'est à dire, est essentiellement constant), est disponible n'importe où, et en faire une copie. Les trois choses nécessaires dans la question d'origine

dans les Constantes.h

@property (strong, nonatomic, readonly) NSArray* array;

et

 + (Constants*)sharedInstance;

puis dans les Constantes.m

#define ARRAY_STRING @"one, two, three, four"  //you seem to be want to be using only NSStrings as the objects in your array. Separate by an otherwise non appearing character or string. could be in constants.h too.

et

  @property (strong, nonatomic, readwrite) NSArray* array;

puis dans le getter de la propriété du tableau vous pouvez utiliser instanciation paresseuse

 - (NSArray*) array
    {
    if (!_array) {
        _array = [[NSArray alloc] init];
        _array = [ARRAY_STRING componentsSeparatedByString:@","]; //because I used a comma to separate the members of my array in this example, but you could use any character or string
    }

    return _array
    }

et pour créer une seule instance

+(Constants*)sharedInstance {
    static Constants *sharedConstants 
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedConstants = [[self alloc] init];
    });
    return sharedConstants;
}

ensuite, lorsque vous souhaitez que le tableau, utilisez la propriété du tableau sur une des Constantes de l'objet. c'est à dire:

    #import "constants.h"

et puis la "constante" de la matrice est

   [Constants sharedInstance].array;

En dehors de Constantes.m, il sera en lecture seule.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X