¿Equivalente constructor estático en Objective-C?


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

Gracias

Author: Quinn Taylor, 2009-06-14

3 answers

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

También quería transmitir un bocado que aprendí que puede morderte en el camino: +initialize se hereda por subclases, y también se llama para cada subclase que no implementa un +initialize de su propio. Esto puede ser especialmente problemático si ingenuamente implementa singleton inicialización 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 métodos +class y -class que devuelven el objeto Class. Dado que solo hay un objeto de clase para cada clase, queremos probar la igualdad con el operador ==. Puede usar esto para filtrar lo que debería suceder solo una vez, versus una vez para cada clase distinta en una jerarquía (que puede no existir todavía) debajo de una clase dada.

En un tema tangencial, vale la pena aprender sobre los siguientes métodos relacionados, si aún no lo ha hecho:


Edit: Echa un vistazo a este post de @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ó una agradable y detallada sesión de preguntas y respuestas del viernes sobre los métodos +initialize y +load : https://www.mikeash.com/pyblog/friday-qa-2009-05-22-objective-c-class-loading-and-initialization.html

 124
Author: Quinn Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-05 18:27:24

Existe el método de clase +initialize que se llamará antes de que se use una clase.

 51
Author: Nathan Kinsinger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-06-14 04:58:53

Un poco de adición a este tema:

Hay otra forma de crear un 'constructor estático' en obj-c, usando 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.
}
 10
Author: Richard J. Ross III,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-05 14:39:28