2009-06-14 28 views
69

Soy nuevo en Objective C y no he podido averiguar si hay el equivalente de un constructor estático en el lenguaje, que es un método estático en una clase que se llamará automáticamente antes de la primera instancia de tal clase es instanciada. ¿O necesito llamar al código de inicialización yo mismo?equivalente constructor estático en Objective-C?

Gracias

Respuesta

121

El método +initialize se llama automáticamente la primera vez que se utiliza una clase, antes de que se usen los métodos de clase o se creen instancias. Nunca debe llamar al +initialize usted mismo.

También quería pasar a lo largo de un bocado supe que pueden morder por el camino: +initialize se hereda por las subclases, y también se llama para cada subclases que no implementa un +initialize de su propia. Esto puede ser especialmente problemático si implementa ingenuamente la inicialización de singleton en +initialize. La solución es comprobar el tipo de la variable de clase, así:

+ (void) initialize { 
    if (self == [MyParentClass class]) { 
    // Once-only initializion 
    } 
    // Initialization for this class and any subclasses 
} 

Todas las clases que descienden de NSObject tienen ambos +class y -class métodos que devuelven el objeto Class. Como solo hay un objeto Class para cada clase, queremos probar la igualdad con el operador ==. Puede usar esto para filtrar lo que debería suceder solo una vez, frente a una vez para cada clase distinta en una jerarquía (que aún no existe) debajo de una clase determinada.

En un tema tangencial, vale la pena aprender acerca de los siguientes métodos relacionados, si no lo ha hecho:


Editar: Control hacia fuera este mensaje por @bbum que explica más sobre +initialize: http://www.friday.com/bbum/2009/09/06/iniailize-can-be-executed-multiple-times-load-not-so-much/

Además, Mike Ash escribió un buen detallada Viernes Q & A sobre los +initialize y +load métodos: https://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html

+5

"if ([self class] == [Clase MyParentClass])" '[self class]' es redundante aquí. usted puede decir 'if (self == [MyParentClass class])' – user102008

+1

¡Gracias! Tu tidbit respondió mi pregunta de por qué un inicializador estático en particular se invocaba dos veces. –

51

No es el método +initialize clase que se llama antes de que se utiliza una clase.

+0

Gracias, eso es exactamente lo que estaba buscando, pero me hicieron búsquedas a "init estática", "inicializador estático", etc., y no lo encontró. –

+8

En casi todos los casos, donde en Java dices "estático", dices "clase" en Objective-C. – Chuck

10

Un poco de un apéndice a este tema:

Hay otra manera de crear un 'constructor estático' i n obj-c, utilizando una directiva __attribute:

// prototype 
void myStaticInitMethod(void); 

__attribute__((constructor)) 
void myStaticInitMethod() 
{ 
    // code here will be called as soon as the binary is loaded into memory 
    // before any other code has a chance to call +initialize. 
    // useful for a situation where you have a struct that must be 
    // initialized before any calls are made to the class, 
    // as they would be used as parameters to the constructors. 
    // e.g. 
    myStructDef.myVariable1 = "some C string"; 
    myStructDef.myFlag1 = TRUE; 

    // so when the user calls the code [MyClass createClassFromStruct:myStructDef], 
    // myStructDef is not junk values. 
} 
+2

+ load hará lo mismo y se verá más sincronizado con el paradigma de Objective-C –

+0

@Grady Nope, específicamente enumero una situación en la publicación donde + load NO es equivalente. –

+0

+ initialize sería diferente, pero + load debería ser el mismo ¿no? –

Cuestiones relacionadas