16

Soy nuevo en Objective-C y estoy intentando comprender la gestión de memoria para hacerlo bien.¿Cuándo se lanza realmente un objeto de autorretrato?

Después de leer el excelente
Memory Management Programming Guide for Cocoa por Apple mi única preocupación es cuando realidad un objeto autoreleased se libera en un archivo/iPod aplicación para el iPhone. Según tengo entendido, al final de ejecutar el ciclo. Pero, ¿qué define un ciclo de ejecución en la aplicación?

Así que me preguntaba si el siguiente fragmento de código es correcto. Suponer un objeto

@implementation Test 

- (NSString *) functionA { 
    NSString *stringA; 
    stringA = [[[NSString alloc] initWithString:@"Hello"] autorelease] 
    return stringA; 
} 

- (NSString *) functionB { 
    NSString *stringB; 
    stringB = [self functionA]; 
    return stringB; 
} 

- (NSString *) functionC { 
    NSString *stringC; 
    stringC = [self functionB]; 
    return stringC; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    NSString* p = [self functionC]; 
    NSLog(@"string is %@",p); 
} 

@end 

¿Este código es válido?

A partir del texto de manzana entiendo que el NSString regresó de funciónA es válido en el ámbito de funciónB. No estoy seguro de si es válido en función C y en viewDidLoad.

Gracias!

Respuesta

17

Sí, sus funciones son válidas y devuelve objetos utilizando las convenciones de Cocoa correctas para conservar/liberar/liberar automáticamente/copiar.

Para responder a su pregunta sobre qué es el runloop, en la función main() de la aplicación, invoca UIApplicationMain(). Se puede imaginar UIApplicationMain ve algo como esto:

void int UIApplicationMain (int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName) { 
    UIApplication *app = /* create app using principalClassName */; 
    [app setDelegate:/* create delegate using delegateClassName */]; 
    while (![app shouldTerminate]) { 
     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
     event = [app getNextEvent]; 
     [app dispatchEvent:event]; 
     [pool drain]; 
    } 
} 

que los bucles while es similar a lo que el UIKit está haciendo realidad, y cada viaje a través de ese bucle while es como un viaje a través de la runloop, donde los bloques de función GetNextEvent de espera para que algún evento ocurra Todos sus métodos son típicamente llamados desde algo como dispatchEvent :. Puede intentar establecer un punto de interrupción en uno de sus métodos, como un IBAction, y buscar en la pila de llamadas al depurador en la parte superior para ver los nombres de los métodos UIKit que manejan los eventos y runloop. Como cada uno de sus métodos se invoca desde ese ciclo while, cada vez que se llama a liberación automática en un objeto, ese objeto se agrega a ese conjunto de puntos en el ciclo de ejecución. Cuando finaliza el envío del evento actual, se vacía el grupo y finalmente se envían los mensajes de lanzamiento.

Una última nota. Puede haber más de un grupo de autorrelease, que no siempre se encuentran al final del ciclo de evento. A veces puede asignar decenas de miles de objetos en un solo viaje a través del ciclo de eventos. Cuando eso suceda, puede configurar pools de autodesbloque interno adicionales en sus propios métodos para mantener baja la cantidad de objetos liberados automáticamente en los grupos de autorelease. Los grupos de versiones automáticas se pueden apilar.

+0

¿Entiendo correctamente que si no creo ningún conjunto de autorreleases, todas las variables autorretractadas permanecerán en la memoria hasta que la aplicación no se cierre? – Burjua

+0

En realidad, los marcos del sistema crean algunos grupos de liberación automática para usted en la parte superior de la pila del hilo principal en métodos como UIApplicationMain(). Sin embargo, si comenzó su propio hilo y no creó un grupo, entonces sí esos objetos se fugarían. El método de liberación automática se registra en la consola en ese caso. –

+0

Ok, gracias, pero esto es extraño, es una práctica normal usar constructores que devuelven objetos liberados automáticamente y no los liberan, pero en realidad es lo mismo que tener pérdida de memoria (la memoria se asigna hasta que se cierra la aplicación). O no entiendo algo? – Burjua

0

No hay nada de malo en ese código. Se compilará y ejecutará como usted espera.

El objeto NSString regresó de functionA sigue siendo válida a su regreso, ya que está siendo transmitida la pila para el siguiente tipo (functionB) que ahora es hacer el seguimiento de la misma.

+3

"Pasó por la pila" probablemente no sea la mejor opción de frase porque implica que se usa una pila para los valores de devolución, lo que no siempre es el caso. –

Cuestiones relacionadas