Pregunta

O mi depurador está roto o hay algo fundamental que yo no soy la comprensión.

Tengo algo de código muy básico en un programa muy básico línea de comandos que debe accidente. Sin embargo, no está fallando.

int main (int argc, const char * argv[])
{
    NSString *string = [[NSString alloc] initWithString:@"Hello"];

    [string release];

    NSLog(@"Length: %d", [string length]);

    return 0;
}

La declaración de registro de impresiones "Longitud: 5", como se puede esperar de una cadena válida. Sin embargo, la cadena debe cancelar la asignación por ese punto y un error exec_bad_access debe ser desechado.

He probado este código con el depurador asociado y sin el depurador asociado - ambos dan el mismo resultado. También he permitido (y discapacitados) NSZombie, que parece tener ningún efecto (al principio pensé que era el problema, ya que los objetos NSZombie no se cancela la asignación - pero todavía no se estrella con NSZombie desactivado).

Tengo puntos de interrupción en mi archivo .gdbinit local para romper en cosas tales como -[NSException raise] y objc_exception_throw. También tengo los puntos de corte establecidos en muchos métodos en NSZombie con el fin de atraparlos.

fb -[NSException raise]
fb -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:]
fb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:]

#define NSZombies
# this will give you help messages.  Set to NO to turn them off.
set env MallocHelp=YES
# might also be set in launch arguments.
set env NSZombieEnabled=YES
set env NSDeallocateZombies=NO
set env MallocCheckHeapEach=100000
set env MallocCheckHeapStart=100000
set env MallocScribble=YES
set env MallocGuardEdges=YES
set env MallocCheckHeapAbort=1

set env CFZombie 5

fb -[_NSZombie init]
fb -[_NSZombie retainCount]
fb -[_NSZombie retain]
fb -[_NSZombie release]
fb -[_NSZombie autorelease]
fb -[_NSZombie methodSignatureForSelector:]
fb -[_NSZombie respondsToSelector:]
fb -[_NSZombie forwardInvocation:]
fb -[_NSZombie class]
fb -[_NSZombie dealloc]

fb szone_error
fb objc_exception_throw

Con estos puntos de corte establecidos y NSZombie habilitados, que debería obtener algo así como [NSString length]: message sent to deallocated instance 0x100010d39 impresa en la consola, pero no ver esto. Veo la NSLog imprimir la longitud que 5.

Veo un comportamiento similar con otras clases, tales como NSURL y NSNumber. Sin embargo, algunas clases de impacto que se esperaba, como NSError y NSObject.

¿Tiene esto algo que ver con los grupos de clase? ¿Es que no siguen las mismas reglas en lo que respecta a la gestión de memoria?

Si los grupos de clase no están relacionados con este problema, la única otra característica común que pude ver fue que las clases que no choque de esta manera son todos sin cargo al puente con una contraparte Fundación Core. Podría esto tener algo que ver con eso?

¿Fue útil?

Solución

retain / release es un contrato entre el API y el programador que cuando se sigue la regla, no se cuelga. El contrato no garantiza que si no se sigue la regla, que se estrella!

En este caso,

[[NSString alloc] initWithString:@"Hello"]

sólo devuelve el mismo objeto que @"Hello" como una optimización. El NSString constante no se cancela la asignación; como una optimización, retain y release son (creo) ignorado. Es por eso que no se desplome.

Puede comprobar mi suposición comparando el valor del puntero de @"Hello" y string.

Otros consejos

Este es un excelente ejemplo de por qué retienen los recuentos son una herramienta de depuración bastante inútil. Es un error suponer -retain y -RELEASE siempre agregar o quitar 1 del conservan contar y que la retienen recuento es lo que usted piensa que debería ser.

Trate

NSString *string = [[NSString alloc] initWithFormat:@"Hello %d", argc];

Esto debe darle una cadena que va a comportarse más como la forma en que está esperando ya que no están inicialización de su cadena a partir de una constante de tiempo de compilación. Sin embargo, se advirtió, con zombis habilitadas, obtendrá el comportamiento que espera pero sin zombis, el NSLog puede trabajar bien. A pesar de que la cadena ha sido desasignado, los datos en el objeto está todavía allí en la memoria dejando un "fantasma" que responda correctamente a algunos mensajes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top