¿Qué es un ciclo de retención en la programación orientada a objetos y por qué es importante?

Los ciclos de retención pueden ocurrir en lenguajes como Objective-C donde la administración de la memoria se basa en el conteo de retención. Los objetos se crean con un recuento de retención de 1. Otros objetos pueden retener el objeto, lo que incrementa el recuento de retención, o liberarlo, lo que disminuye el recuento de retención. Si el recuento de retención de un objeto llega a 0, el tiempo de ejecución lo desasigna. Solo entonces se llama al método dealloc del objeto.

En un caso simple, considere dos objetos A y B donde A crea y retiene B. Cuando se crea A, crea B. Cuando quien creó A finalmente lo libera, el recuento de retención de A cae a cero y se desasigna. Si el método dealloc de A llama a la liberación en B, el recuento de retención de B también cae a cero y también se desasigna. [Esto supone que nadie más ha retenido A o B, porque estoy manteniendo las cosas simples.]

Pero, ¿qué sucede si B necesita una referencia a A y retiene A? Quien haya creado A podría liberarlo. Pero dado que B también retuvo A, el recuento de retención de A no irá a cero. Del mismo modo, dado que A retiene a B, el conteo de retención de B tampoco irá a cero. Ninguno de los dos será desasignado. Incluso si B llama al método de liberación de A en su propio Dealloc, no importa, porque ese método nunca se llamará.

En este punto, tiene una pérdida de memoria, porque no tiene ninguna referencia a A o B a pesar de que ambos todavía existen. Si A o B está haciendo algo intensivo en el procesador, entonces también podría estar perdiendo tiempo de CPU a objetos no deseados.

Para una discusión más detallada de los recuentos retenidos, vea el blog Cocoa with Love en http://cocoawithlove.com/2009/07…