2010-01-06 5 views
24

Digamos que estoy creando una nueva clase para el iPhone en Objective-C. En uno de mis métodos init, quiero asignar memoria manualmente. Por lo tanto, podría tener algo como esto:¿Cómo debo manejar una falla en un método init: en Objective-C?

- (id)initWithSomeObject:(SomeObject *)someObject { 
    self = [super init]; 
    if (self != nil) { 
    myObject = someObject; 
    [myObject retain]; 
    if ((memory = calloc(1, sizeof(SomeStruct)) == NULL) { 
     // What should I do here to clean up 
     [self release]; 
     self = nil; 
    } 
    } 
    return self; 
} 

Ahora, suponiendo que el calloc() podría fallar, y que no se puede asignar memoria es catastrófica para mi objeto, ¿qué debería hacer el interior del cuerpo, si para limpiar arriba correctamente? ¿Hay un modismo o patrón de Objective-C que debería estar usando?

Editar: Incluí el código publicado por Rob Napier. Pero, todavía tengo que lanzar myObject, ¿verdad? ¿O el código agregado de alguna manera desencadena dealloc()?

+2

No se preocupe si desencadena dealloc(). Lo hace, pero ese no es el punto. El punto es que [self release] equilibra la llamada anterior a + alloc, por lo que se han realizado todos los lanzamientos necesarios y el sistema se encargará de la desasignación en el momento apropiado. En la mayoría de los casos, "el momento apropiado" es probable tan pronto como se llame a [auto-lanzamiento], pero podría ser más tarde si hay alguna autorrellena pendiente. Pero el código anterior es correcto y no se requiere nada más. –

+0

Como nota al margen: Entiendo que calloc/malloc nunca devolverá NULL, el sistema simplemente matará su aplicación cuando se quede sin memoria o con poca memoria. Supongo que Apple pensó que era más fácil de hacer que tener la aplicación bloqueando desde punteros NULL/nil sin marcar. –

Respuesta

26

Sí, debe liberarse y luego devolver nil.

[self release]; 
self = nil; 

Ver Issues with Initializers en los conceptos en Objective-C Guía de programación.

3

Debe limpiar todo lo que necesite y luego establecer la referencia automática en nil. Dev Portal de Apple tiene un artículo:

Link

+0

geez - al menos deja un comentario cuando bajas tu voto! – psychotik

+0

No te olvides de liberarte, o tendrás una fuga. (No tengo idea de quién votó en contra, tienes razón). –

1

simplemente he intentado. -dealloc se llama debido a [self release], por lo que myObject no necesitaría ser lanzado en initWithSomeObject. Para estar seguro, puede mover myObject = [someObject retain]; (prefiero ese estilo en caso de que -retain falle por alguna razón) debajo de la llamada que podría fallar (si es posible).

Cuestiones relacionadas