objective c - Cuándo usar-retainCount?
objective-c memory-management (10)
Me gustaría saber en qué situación -retainCount
hasta el momento, y eventualmente los problemas que pueden ocurrir al usarlo.
Gracias.
¡NUNCA!
Seriamente. Simplemente no lo hagas.
Simplemente siga las Pautas de administración de memoria y solo libere lo que haya alloc
, new
o copy
(o cualquier cosa que llame retain
al principio).
@bbum lo dijo mejor aquí en SO , y con aún más detalle en friday.com/bbum/2011/12/18/retaincount-is-useless .
¿Qué problemas puedes obtener al usarlo? Todo lo que hace es devolver el conteo retenido del objeto. Nunca lo llamé y no puedo pensar en ninguna razón por la que lo haría. Lo he anulado en singletons para asegurarme de que no estén desasignados.
Eche un vistazo a la documentación de Apple en NSObject, más o menos cubre su pregunta: NSObject retainCount
En resumen, retainCount es probablemente inútil para usted a menos que haya implementado su propio sistema de conteo de referencias (y casi puedo garantizar que no lo tendrá).
En las propias palabras de Apple, retainCount "normalmente no tiene valor en la depuración de problemas de administración de memoria".
Encuentro retenerCuentas muy útil cuando se comprueba con ''Instrumentos''.
Con la herramienta ''asignaciones'', asegúrese de que ''Grabar recuentos de referencia'' esté activado y de que pueda acceder a cualquier objeto y ver su historial de conservación de reservas.
Al combinar los allocs y releases, puede obtener una buena idea de lo que está sucediendo y, a menudo, resolver aquellos casos difíciles en los que algo no se está divulgando.
Esto nunca me ha decepcionado, incluyendo la búsqueda de errores en versiones beta tempranas de iOS.
Los objetos lanzados automáticamente son un caso en el que la comprobación de -retainCount es poco informativa y potencialmente engañosa. El conteo de retención no le dice nada sobre cuántas veces se ha llamado a un objeto y, por lo tanto, a la cantidad de tiempo que se liberará cuando se vacíe el grupo de autorrelease actual.
No debe preocuparse por la pérdida de memoria hasta que su aplicación esté en funcionamiento y haciendo algo útil.
Una vez que esté encendido, enciende los instrumentos y utiliza la aplicación para ver si realmente ocurren filtraciones de memoria. En la mayoría de los casos, usted creó un objeto usted mismo (por lo tanto, lo posee) y se olvidó de liberarlo después de que haya terminado.
No intente ni optimice su código mientras lo está escribiendo; sus conjeturas sobre qué puede perder memoria o si tomar demasiado tiempo a menudo son incorrectas cuando realmente usa la aplicación normalmente.
Intente y escriba el código correcto, por ejemplo, si crea un objeto usando alloc y tal, luego asegúrese de liberarlo correctamente.
Nunca debe usar -retainCount
, porque nunca le dice nada útil. La implementación de los frameworks Foundation y AppKit / UIKit es opaca; no sabe qué se retiene, por qué se retiene, quién lo conserva, cuándo se retuvo, etc.
Por ejemplo:
- Uno pensaría que
[NSNumber numberWithInt:1]
tendría unretainCount
de 1. No es así. Es 2. - Uno pensaría que
@"Foo"
tendría unaretainCount
de 1. No es así. Es 1152921504606846975. - Uno pensaría que
[NSString stringWithString:@"Foo"]
tendría unretainCount
deretainCount
de 1. No es así. Nuevamente, es 1152921504606846975.
Básicamente, dado que cualquier elemento puede retener un objeto (y, por lo tanto, alterar su retainCount
), y como no tiene el origen para la mayoría del código que ejecuta una aplicación, el retainCount
de retainCount
un objeto retainCount
tiene sentido.
Si intenta rastrear por qué un objeto no se desasigna, utilice la herramienta Fugas en Instrumentos. Si intenta rastrear por qué un objeto fue desasignado demasiado pronto, use la herramienta Zombies en Instruments.
Pero no use -retainCount
. Es un método realmente sin valor.
editar
Todos van a http://bugreport.apple.com y solicitan que -retainCount
se -retainCount
. Cuantas más personas lo pidan, mejor.
editar # 2
Como actualización, [NSNumber numberWithInt:1]
ahora tiene un retainCount
de 9223372036854775807. Si su código esperaba que fuera 2, su código ahora se ha roto.
Nunca deberías usarlo en tu código, pero definitivamente podría ayudar cuando se depura
Nunca use el -retainCount en su código. Sin embargo, si usa, nunca verá que devuelve cero. Piensa por qué. :-)
Por supuesto, nunca debes usar el método retainCount en tu código, ya que el significado de su valor depende de cuántas autorreleases se hayan aplicado al objeto y eso es algo que no puedes predecir. Sin embargo, es muy útil para la depuración, especialmente cuando busca pérdidas de memoria en el código que llama a métodos de objetos de Appkit fuera del ciclo de eventos principales, y no debe ser desaprobado.
En su esfuerzo por expresar su punto, usted exageró en gran medida la naturaleza inescrutable del valor. Es cierto que no siempre es un recuento de referencia. Hay algunos valores especiales que se utilizan para indicadores, por ejemplo, para indicar que un objeto nunca debe ser desasignado. Un número como 1152921504606846975 se ve muy misterioso hasta que lo escribe en hexadecimal y obtiene 0xfffffffffffffff. Y 9223372036854775807 es 0x7fffffffffffffff en hexadecimal. Y realmente no es tan sorprendente que alguien elija usar valores como estos como indicadores, dado que tomaría un valor de retención de hasta 3000 años para obtener un valor de retención tan alto como el número mayor, suponiendo que incrementó el valor de retención 100,000,000 por segundo.