2011-03-03 20 views
16

Para los desarrolladores de iOS, los delegados se utilizan en casi todas partes.propiedad "asignar" y "retener" para delegado

Y parece como que tenemos que utilizar "ceder" en vez de retener a un delegado como esto

La razón es evitar el problema de bucle circular Why are Objective-C delegates usually given the property assign instead of retain?

vi una gran cantidad de código y todavía usaban "retener". Entonces, la pregunta aquí es: ¿seguiremos recibiendo el problema del ciclo circular si usamos retener para un delegado?

Gracias

Respuesta

26

El documentation dice:

la retención de un objeto crea una fuerte referencia, y un objeto no puede cancelar la asignación hasta que todos sus fuertes referencias son liberados. Si dos objetos conservan entre sí, ni objeto alguna vez se cancela la asignación debido a que la conexión entre ellos no puede ser quebrantada

A modo de ejemplo, consideremos un UITableViewController que implementa el protocolo UITableViewDelegate. UITableView es retenido por su controlador de vista, aunque el UITableView no conserva su delegado.

Como dije en el documento anterior, UITableViewController solo completará su desasignación cuando se publiquen todas sus sólidas referencias. Como el UITableView que tiene el UItableViewController como delegado no lo retiene, cuando el propietario de las llamadas a UItableViewController lo libera, el conteo de retención se pondrá a cero y se llamará al método dealloc.

Ahora imagina que UITableView conserva su delegado. UITableViewController tendrá un conteo retenido de al menos +2. Uno con su propietario y otro con UITableView. Cuando las llamadas del propietario de UITableViewController lanzan sobre él, el conteo retenido irá a +1, y no a cero como se esperaba, por lo que no se llamará al método dealloc hasta que el conteo retenido llegue a cero. Para llegar a cero, UITableViewController necesitaría liberar su UITableView que luego liberaría su delegado (UITableViewController). Debido a que UITableViewController solo dispondrá de su vista (UITableView) cuando desasignar este momento nunca ocurrirá porque el conteo retenido no irá por debajo de +1.

(no hay que tomar en consideración las advertencias de memoria y cualquier otro caso posible ... Acabo de ver que ViewController/Vista no es la mejor opción para este ejemplo, pero he escrito demasiado. :))

¿Eso tiene sentido?

+0

Sí, ¡haz un gran sentido y muchas gracias! En su caso, A es UITableViewController, B es TableView, por lo que la única forma correcta es utilizar la "asignación" para delegar en TableView. Considere otro caso común, A es ViewController, B es otro ViewController, A crea un nuevo B, y usa "retener" para delegado en B, y también A puede liberar el B, en este caso, "retener" está bien para delegar en B. ¿Tiene sentido? – Forrest

+0

No lo consiguió. Usted dice que A crea B, A usa B como delegado para algo, y entonces, A.viewController (retener) = B, y A.delegar (asignar) = B. O A es delegado en B, y entonces, A. viewController (retener) = B, y B.delegate (assign) = A? ¿Cuál es el caso? – vfn

+0

El contexto sobre A y B proviene del enlace ¿Por qué a los delegados de Objective-C generalmente se les asigna la propiedad en lugar de retener? – Forrest

Cuestiones relacionadas