2012-09-06 14 views
13

tengo este código:"El elemento inicializador no es una constante en tiempo de compilación" ¿por qué?

- (NSString *) calculate: (uint) position { 
    static NSArray * localArray = [NSArray arrayWithArray: self.container.objects ]; 
    // some un related code 
    return obj; 
} 

El compilador se queja diciendo: "elemento inicializador no es una constante de tiempo de compilación". Sucedió cuando agregué "static" a localArray. ¿Pero por qué?

+0

http://stackoverflow.com/q/6143107/94687 fue la misma pregunta. Lo único especial en su pregunta es la adición explícita de la palabra clave 'static' a una variable dentro de un cuerpo de función (pero esto debe ser equivalente a tener una variable en el ámbito global, como en esa pregunta). –

Respuesta

28

Como [NSArray arrayWithArray: self.container.objects ] no es una constante en tiempo de compilación, es una expresión que debe evaluarse en tiempo de ejecución. En C y Objective-C, static las variables dentro de las funciones se deben inicializar con en tiempo de compilación constantes, mientras que C++ y Objective-C++ son más indulgentes y permiten constantes que no son de compilación.

Cualquiera de compilar el código como Objective-C++ o refactorizar en algo como esto:

static NSArray *localArray = nil; 
if (localArray == nil) 
    localArray = [NSArray arrayWithArray: self.container.objects ]; 

que es bastante similar al código que el compilador generaría bajo el capó de una variable static inicializado con una constante de tiempo de no compilación (en realidad, utilizaría una segunda bandera global que indica si el valor se inicializó, en lugar de utilizar un valor centinela como nil aquí; en este caso, asumimos que localArray nunca será nil). Puede consultar el desensamblador de su compilador si lo desea.

+2

Recomiendo usar 'dispatch_once()' para inicializar 'localArray'. Es seguro para subprocesos y muy eficiente. – bbum

5

Simplemente no puede inicializar una variable estática con un valor no estático que se conocerá/modificará en el tiempo de ejecución.

Probablemente debería hacer algo como esto:

static NSArray *localArray = nil; 
localArray = ...; 

La primera instrucción se ejecutará una vez en su ciclo de vida de aplicaciones. La segunda instrucción se ejecutará cada vez que se llame al método calculate :.

Sin embargo, preste atención al hecho de que el uso de variables estáticas puede conducir a comportamientos erróneos si no se realiza correctamente, por lo que si se siente incómodo con estos, probablemente no los use.

+2

+1 "La primera instrucción se ejecutará una vez en el ciclo de vida de su aplicación." – Philip007

Cuestiones relacionadas