objective c - ¿Cuándo se libera realmente un objeto lanzado automáticamente?
objective-c iphone (2)
Soy nuevo en object-c y trato de entender la administración de la memoria para hacerlo bien.
Después de leer el excelente.
Guía de programación de la gestión de la memoria para Cocoa by Apple, mi única preocupación es cuando en realidad se lanza un objeto lanzado automáticamente en una aplicación de iPhone / iPod. Mi comprensión está al final de un bucle de ejecución . Pero, ¿qué define un bucle de ejecución en la aplicación?
Así que me preguntaba si el siguiente fragmento de código es correcto. Asumir 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
¿Es este código válido?
Del texto de Apple entiendo que el NSString devuelto desde functionA es válido en el alcance de functionB . No estoy seguro de si es válido en functionC y en viewDidLoad .
¡Gracias!
No hay nada malo con ese código. Se compilará y se ejecutará como se espera.
El objeto NSString
devuelto por functionA
todavía es válido al regresar ya que se pasa de la pila al siguiente tipo ( functionB
) que ahora lo está siguiendo.
Sí, sus funciones son válidas y devuelven objetos utilizando las convenciones de Cocoa correctas para retener / liberar / autorelease / copy.
Para responder a su pregunta sobre qué es el runloop, en la función main () de su aplicación, invoca UIApplicationMain (). Puedes imaginar que UIApplicationMain se parece a 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 son similares a lo que realmente hace el UIKit, y cada viaje a través de ese bucle while es como un viaje a través del runloop, donde la función getNextEvent bloquea la espera de que ocurra algún evento. Todos sus métodos se suelen llamar desde algo como dispatchEvent :. Puede intentar establecer un punto de interrupción en uno de sus métodos, como una IBAction, y buscar en la pila de llamadas del depurador en la parte superior para ver los nombres de los métodos UIKit que manejan los eventos y el runloop. Dado que cada uno de sus métodos se llama desde ese bucle while, cada vez que se llama autorelease en un objeto, ese objeto se agrega a ese grupo externo en el bucle de ejecución. Cuando el evento actual termina de enviarse, la agrupación se drena y esos objetos finalmente se envían mensajes de liberación.
Una última nota. Puede haber más de un grupo de autorelease, que no siempre están al final del bucle de eventos. A veces, puede asignar decenas de miles de objetos en un viaje a lo largo del ciclo de eventos. Cuando eso suceda, puede configurar grupos de liberación automática internos adicionales con sus propios métodos para mantener bajo el número de objetos lanzados automáticamente. Los grupos de liberación automática pueden apilarse.