objective-c memory-management class-method initializer

objective c - Métodos de clase que crean nuevas instancias



objective-c memory-management (4)

Estos métodos simplemente devuelven una versión de autorreleases del objeto.

+(MyClass*)class { MyClass* object = [[MyClass alloc] init]; return [object autorelease]; }

Además del patrón estándar [[MyClass alloc] init] , algunos objetos se crean a partir de métodos estáticos como MyClass *obj = [MyClass classWithString:@"blabla"]

Según las guías de administración de memoria generalizadas (incluida la de Apple), solo eres responsable de liberar los objetos que alloc .

¿Alguien puede proporcionarme una plantilla para tales métodos? ¿Cómo devuelve el objeto asignado ( [self alloc]; return self; quizás)? ¿Cómo te aseguras de que sea lanzado?


La forma moderna de hacer esto con ARC y el último compilador es:

+ (instancetype) myClassWithString:(NSString *)string { return [[MyClass alloc] initWithString:string]; }

  • No es necesario realizar una liberación automática con ARC.
  • instancetype proporciona mejores comprobaciones de tiempo de compilación mientras hace posible la creación de subclases.

Los objetos devueltos de los métodos de fábrica se deben liberar automáticamente, lo que significa que se limpiarán cuando se vacíe el grupo de autorrelease asociado. Esto significa que usted no posee los objetos devueltos a menos que los copy o retain . A continuación se muestra un ejemplo de un método de fábrica:

+ (id)myClassWithString:(NSString *)string { return [[[MyClass alloc] initWithString:string] autorelease]; }


Son métodos de clase, no métodos estáticos 1 . Este tipo específico, la creación de objetos liberados automáticamente, se puede denominar "métodos de fábrica" ​​(anteriormente también "constructores de conveniencia"), y se tratan en la Guía Conceptos en ObjC . Ellos dicen algo como esto:

+ (instancetype)whatsisWithThingummy: (Thingummy *)theThingummy { return [[self alloc] initWithThingummy:theThingummy]; }

Donde Whatsis es tu clase, y Thingummy es otra clase que tu clase usa.

Si no está compilando con ARC, la convención es autorelease la instancia antes de devolverla.

Clang introdujo la palabra clave instancetype para este tipo de métodos; combinado con self (que es el objeto de clase en2 en un método de clase) permite el comportamiento correcto de subclase: el método produce una instancia de la clase que recibió el mensaje. 3 tipo de instancetype permite al compilador hacer una comprobación de tipos más estricta que id .

Una ilustración de este uso en subclases del marco: +[NSString stringWithFormat:] devuelve una instancia de NSString , mientras que +[NSMutableString stringWithFormat:] , devuelve una instancia de la subclase NSMutableString , sin que sea necesario NSMutableString para anular explícitamente el método.

Como se menciona en [ Fundamentals ] [1] doc, hay otros usos para estos métodos de fábrica, como el acceso a un singleton, o la evaluación de la asignación de memoria necesaria antes de que se realice (posible, pero menos conveniente , con un alloc / init estándar par).

1 "Métodos estáticos" en Java o C ++, "métodos de clase" en Objective-C. No hay métodos estáticos en ObjC

2 Mientras que en un método de instancia el self es, sensiblemente, una referencia a la instancia.

3 Anteriormente, al igual que los métodos de inicialización habituales ( initWith... ), habría utilizado id como tipo de devolución. El uso de un nombre de clase específico fuerza innecesariamente subclases para anular el método.