2010-05-06 22 views
30

Estoy intentando crear un NSArray con una agrupación de literales de cadenas; sin embargo, aparece el error de compilación "El elemento inicializador no es constante".¿Cómo creo un NSArray con literales de cadena?

NSArray *currencies = [NSArray arrayWithObjects:@"Dollar", @"Euro", @"Pound", nil]; 

¿Podría alguien señalar lo que estoy haciendo mal, y posiblemente explicar el mensaje de error?

+0

Tu código debería funcionar, ¿estás seguro de que el error no está en otra parte? – pheelicks

+0

Debería decir dónde ha puesto esa línea porque parece que no la puso en un método. – malhal

Respuesta

18

Esto no es un problema con la creación de NSArray en sí (obtendría el mismo error si escribió [NSArray array] en su lugar), pero con dónde lo ha escrito. Supongo que se trata de un NSArray global o de archivos estáticos. En C, ese tipo de variable debe tener un inicializador constante, es decir, no una llamada a función (o, por extensión, una llamada a método). La solución es poner la creación y asignación real de la matriz en un método que se llamará antes de necesitar la matriz, como initialize.

+1

Lo había declarado en el archivo de encabezado, pero no era consciente de que no podía inicializarlo fuera de un método. – Kyle

+0

¿sería seguro ponerlo dentro de '+ load'? – user102008

0

No hay nada de malo en ese código. ¿Estás seguro de que el error se produce en esa línea?

2

Soy un novato en Objective-C, pero creo que el código correcto es:

NSArray * monedas = [[alloc] initWithObjects NSArray: @ "Dólar", @ "Euro", @ "Libra", nada];

No estoy seguro tho.

+2

Eso también es válido, sin embargo, no hay nada de malo en el código de OP. Su método simplemente conserva la matriz mientras que no lo hace – pheelicks

+0

Sin embargo, si el objeto almacenado en una variable estática ** no ** se retiene, es un error oculto, por lo que alloc/init sería lo correcto. – jlehr

7

Parece que Chuck ha detectado el problema. Sin embargo, una cosa que debes tener en cuenta al codificar tu solución es que querrás evitar almacenar una instancia liberada de NSArray en una variable estática. Además, un patrón común para estas situaciones es escribir un método de clase que crea y devuelve el valor almacenado en la variable estática, así:

+ (NSArray *)currencies 
{ 
    static NSArray *_currencies; 

    // This will only be true the first time the method is called... 
    // 
    if (_currencies == nil) 
    { 
     _currencies = [[NSArray alloc] initWithObjects:@"Dollar", @"Euro", @"Pound", nil]; 
    } 

    return _currencies; 
} 
+0

Hola, ¿por qué no se recomienda almacenar objetos liberados automáticamente en variables estáticas? ¿Es por eficiencia para que no se les pregunte su retención cuentan en cada ciclo? –

+1

Los objetos en un grupo de autorrelease no se les pide su conteo de retención; se les envía un mensaje de 'liberación' cuando se lanza el grupo de liberación automática.Si un objeto liberado automáticamente se almacena en una variable estática, la variable contendrá una dirección no válida cuando esto ocurra, e intentará hacer referencia a ella, ya sea que bloqueará el programa o, lo que es peor, hará que acceda de forma incorrecta a algún objeto nuevo asignado en ese momento. dirección en el ínterin. – jlehr

+0

Sí, esto es cierto, los documentos también establecen que si retiene un objeto de liberación automática, su objeto no será desasignado cuando se agote el conjunto. Si usa el appkit, se creará un grupo de liberación automática en cada ciclo de evento y se agotará al final del mismo. Así que creo que se llama retener el conteo. –

3

Aunque esto es viejo, por favor notar que Apple cometió un nuevo parche para el proyecto llvm agrega compatibilidad con la nueva sintaxis literal de Objective-C para NSArray, NSDictionary y NSNumber.

Ver here y here

67

probar este mágico:

NSArray *currencies = @[@"Dollar", @"Euro", @"Pound"]; 

Y sí que debe haber dentro de un método.

+0

Merece la pena notar que se va a asignar una matriz dinámicamente si está dentro del método. Esperaba que fuera una matriz constante estática. – Andy

Cuestiones relacionadas