¿Cómo verifico el conteo de references en el modo ARC?

Solía ​​verificar que algunas de mis variables tenían el recuento de retención esperado utilizando [myVar retainCount] debajo del depurador, especialmente para var que no tenía un desalocador personalizado.

¿Cómo haces esto en modo ARC? ¿Cómo se asegura de que no haya pérdidas de memory?

Nota: Entiendo que ARC debe manejar esto para mí, pero la vida está lejos de ser perfecta, y en la vida real tiene objects que a veces son asignados por bibliotecas de terceros (¿utilizando retener?) Y nunca se desasignan.

Imagen que hago esto:

MyObj *myObj=[[MyObj alloc] init]; 

entonces llamo

 [somethingElse doSomethingWithMyObj:myObj]; 

y luego hago

 myObj=NULL; 

Si mi progtwig funciona bien, mi expectativa es que myObj esté siendo destruido, pero parece que no es el caso …

Entonces, ¿cómo puedo rastrear esto, especialmente si algo Else no es administrado por mí?

Ahora, sobre las herramientas: parece extremadamente difícil ejecutar herramientas de memory en mi Mac (con 5 Meg) sin reiniciar el Mac y comenzar de cero. ¡Esto es realmente molesto! Los instrumentos siguen chocando incluso antes de que el progtwig haya comenzado, entonces ¿hay alguna solución alterante?

Puede usar CFGetRetainCount con objects Objective-C, incluso bajo ARC:

 NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject)); 

Esto no es particularmente útil para la debugging, sin embargo, por razones ampliamente descritas en otros lugares . Si necesita comprender dónde se retiene y libera un object, consulte esta respuesta para get ayuda con el instrumento Asignaciones.

El único caso en el que he encontrado dónde examinar el conteo de retención es realmente útil está en un método dealloc , cuando algo retiene y autorelea el object que se está desasignando. Esto causará un locking más tarde cuando se vacíe la agrupación de autorelease. Puede determinar la causa de esto comprobando el recuento de retención antes y después de cada post. De esta manera, descubrí que el método observationInfo (que en sí mismo solo es útil para la debugging) conserva y autorea. Sin embargo, incluso este tipo de problema generalmente se puede resolver sin examinar el recuento de retención, simplemente envolviendo todo el cuerpo de dealloc en un bloque @autoreleasepool .

Sin embargo, el conteo de retención se puede usar para aprender sobre la implementación de algunas classs. (¡Solo haz esto por entretenimiento o curiosidad! ¡Nunca confíes en los detalles de implementación indocumentados en el código de producción!)

Por ejemplo, intente esto inmediatamente dentro del @autoreleasepool en main :

 NSNumber *n0 = [[NSNumber alloc] initWithInt:0]; NSLog(@"0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef)n0)); // Prints 2 in my test 

Entonces NSNumber almacena en caching (o al less reutiliza) algunas instancias. Pero no a otros:

 n0 = [[NSNumber alloc] initWithInt:200]; NSLog(@"n0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n0)); // Prints 1 - I am the sole owner of this instance. There could be weak // or unretained references to it, but no other strong references. NSNumber *n1 = [[NSNumber alloc] initWithInt:200]; NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1)); // Prints 1 again. New instance with same value as prior instance. // You could of course compare pointers to see that they are separate // instances. 

Incluso puede descubrir que NSNumber devuelve un singleton si alloc pero no inicializa:

 n1 = [NSNumber alloc]; NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1)); // Prints -1. 

(Tenga en count que también puede aprender muchos detalles sobre NSNumber si mira el código fuente de Core Foundation, que está disponible en http://opensource.apple.com . Pero quién sabe qué puede encontrar si observa la count de retención de objects que no tienen un puente de connection libre con los objects en Core Foundation?)

No lo haces. ARC maneja la gestión de memory para usted y no le permite llamar a retainCount e incluso si pudiera verlo, el número que regresa no tiene sentido para usted. Si lo desea, debería estar haciendo perfiles de memory en Instrumentos con los instrumentos de Fugas y Asignaciones. Esa es la mejor manera de ver y ver cómo su aplicación está asignando memory y detecta cualquier uso inadecuado de la memory allí.

Nunca debe usar retainCount para nada, con o sin ARC.

¿Cuándo usar -retainCount?

Use Instrumentos y localice el object que desea rastrear buscando el nombre de la class o la dirección del puntero si lo tiene mientras está en "Lista de objects".

Cuando lo haya localizado, presione la flecha de divulgación en la instancia. Esto te lleva a una vista de historial para retiene y relases.

Si expande la vista de detalles del lado derecho, también verá el callstack para cada retención / liberación.

Instrumentos que muestran el historial de objetos y los detalles de la pila de llamada.

Creo que la única forma es perfilar su aplicación utilizando el instrumento de Asignaciones. Deberá hacer clic en el descriptor de información (la "i" junto a la asignación en el panel izquierdo) y hacer clic en "Grabar references de reference". A continuación, puede perfilar su aplicación y hacer una búsqueda de la class específica que está buscando para inspeccionar. Desde allí, puede encontrar el recuento de retención en el panel de Detalle ampliado para cada instancia de la class.

También puedes hacer esto usando Fugas también (ya que creo que es una variación del instrumento de Asignaciones).

¿Obtiene retainCount del object?

Puede hacer un punto de interrupción e ingresar el command a continuación para get el retainCount de retainCount del object

 po object.retainCount 

No lo haces. Apple dice que no es necesario, ya que ARC se encargará de ti.

Se supone que no se preocupa por retainCount . Se supone que debe escribir su código correctamente y esperar que las bibliotecas que usa también estén escritas correctamente.