Me gustaría saber en qué situación lo usó -retainCount
hasta ahora y, eventualmente, los problemas que pueden ocurrir al usarlo.
Gracias.
Me gustaría saber en qué situación lo usó -retainCount
hasta ahora y, eventualmente, los problemas que pueden ocurrir al usarlo.
Gracias.
Respuestas:
Nunca debes usarlo -retainCount
, porque nunca te dice nada útil. La implementación de los marcos Foundation y AppKit / UIKit es opaca; no sabe qué se retiene, por qué se retiene, quién lo retiene, cuándo se retiene, etc.
Por ejemplo:
[NSNumber numberWithInt:1]
tendría un valor retainCount
de 1. No es así. Es 2.@"Foo"
tendría un valor retainCount
de 1. No es así. Es 1152921504606846975.[NSString stringWithString:@"Foo"]
tendría un valor retainCount
de 1. No es así. Nuevamente, es 1152921504606846975.Básicamente, dado que cualquier cosa puede retener un objeto (y por lo tanto alterarlo retainCount
), y dado que no tienes la fuente para la mayor parte del código que ejecuta una aplicación, un objeto no retainCount
tiene sentido.
Si está tratando de rastrear por qué un objeto no se desasigna, use la herramienta Fugas en Instrumentos. Si está intentando averiguar por qué se desasignó un objeto demasiado pronto, utilice la herramienta Zombies en Instrumentos.
Pero no lo use -retainCount
. Es un método verdaderamente inútil.
editar
Por favor, todos vayan a http://bugreport.apple.com y soliciten que -retainCount
quede obsoleto. Cuanta más gente lo pida, mejor.
editar # 2
Como actualización, [NSNumber numberWithInt:1]
ahora tiene un retainCount
9223372036854775807. Si su código esperaba que fuera 2, su código ahora se ha roto.
- (NSUInteger)retainCount{return NSUIntegerMax;}
.
retainCount
.
Seriamente. Simplemente no lo hagas.
Sólo tiene que seguir la directrices de gestión de memoria y sólo soltar lo que alloc
, new
o copy
(o cualquier cosa que llamó retain
al principio).
@bbum lo dijo mejor aquí en SO , e incluso con más detalle en su blog .
-retainCount
se puede obtener (con mucho más detalle) de Instruments y sus herramientas.
retain
, retain
, retain
, autorelease,
autorelease, autorelease
podría ser un resultado perfectamente válido de pasar un objeto a través de la API UIKit, por ejemplo.
Los objetos liberados automáticamente son un caso en el que la comprobación de -retainCount no es informativa y es potencialmente engañosa. El recuento de retención no le dice nada sobre cuántas veces se ha llamado a -autorelease en un objeto y, por lo tanto, cuántas veces se liberará cuando se agote el grupo de autorelease actual.
Yo no encuentro retainCounts muy útiles en caso de control mediante 'instrumentos'.
Con la herramienta 'asignaciones', asegúrese de que 'Registrar recuentos de referencias' esté activado y de que pueda acceder a cualquier objeto y ver su historial de retención de cuentas.
Al emparejar asignaciones y lanzamientos, puede obtener una buena imagen de lo que está sucediendo y, a menudo, resolver esos casos difíciles en los que algo no se está lanzando.
Esto nunca me ha defraudado, incluida la búsqueda de errores en las primeras versiones beta de iOS.
Eche un vistazo a la documentación de Apple sobre NSObject, prácticamente cubre su pregunta: NSObject keepCount
En resumen, retenerCount probablemente sea 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, retenerCount "normalmente no tiene ningún valor para depurar problemas de gestión de memoria".
Por supuesto, nunca debe usar el método retenerCount en su código, ya que el significado de su valor depende de cuántas autorizaciones se hayan aplicado al objeto y eso es algo que no puede predecir. Sin embargo, es muy útil para la depuración, especialmente cuando busca fugas de memoria en el código que llama a métodos de objetos de Appkit fuera del bucle de eventos principal, y no debe quedar obsoleto.
En su esfuerzo por hacer su punto, exageró seriamente la naturaleza inescrutable del valor. Es cierto que no siempre es un recuento de referencia. Hay algunos valores especiales que se utilizan para las banderas, por ejemplo, para indicar que un objeto nunca debe desasignarse. Un número como 1152921504606846975 parece 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 se necesitarían casi 3000 años para obtener un valor de cuenta de retención tan alto como el número mayor, asumiendo que se incrementó la cuenta de retención de 100,000,000 veces por segundo.
¿Qué problemas puede tener al usarlo? Todo lo que hace es devolver el recuento de retención del objeto. Nunca lo he llamado y no puedo pensar en ninguna razón por la que lo haría. Sin embargo, lo he anulado en singletons para asegurarme de que no se desasignen.
retainCount
para la gestión de memoria.
No debe preocuparse por la pérdida de memoria hasta que su aplicación esté funcionando y haciendo algo útil.
Una vez que lo esté, encienda Instrumentos y use la aplicación y vea si realmente ocurren pérdidas de memoria. En la mayoría de los casos, creó un objeto usted mismo (por lo tanto, es de su propiedad) y olvidó liberarlo después de haber terminado.
No intente optimizar su código mientras lo escribe, sus suposiciones sobre lo que puede perder memoria o demorar demasiado a menudo son incorrectas cuando en realidad usa la aplicación normalmente.
Intente escribir el código correcto, por ejemplo, si crea un objeto usando alloc y demás, asegúrese de liberarlo correctamente.
-retainCount
.