¿Por qué a los delegados de Objective-C generalmente se les asigna la propiedad en lugar de retener?


Answers

Porque el objeto que envía los mensajes de delegado no posee el delegado.

Muchas veces, es al revés, como cuando un controlador se establece como delegado de una vista o ventana: el controlador posee la vista / ventana, por lo que si la vista / ventana posee su delegado, ambos objetos se poseerán entre sí. Esto, por supuesto, es un ciclo de retención, similar a una fuga con la misma consecuencia (los objetos que deberían estar muertos permanecen vivos).

Otras veces, los objetos son pares: ninguno posee el otro, probablemente porque ambos pertenecen al mismo tercer objeto.

De cualquier manera, el objeto con el delegado no debe retener su delegado.

(Por cierto, hay al menos una excepción. No recuerdo qué era, y no creo que haya una buena razón para ello).

Addendum (agregado 2012-05-19): En ARC, debe usar weak lugar de assign . Las referencias débiles se configuran como nil automáticamente cuando el objeto muere, lo que elimina la posibilidad de que el objeto delegado termine enviando mensajes al delegado muerto.

Si te mantienes alejado de ARC por alguna razón, al menos cambia las propiedades de assign que apuntan a los objetos a unsafe_unretained , lo que hace explícito que esta es una referencia no retenida pero no cero a un objeto.

assign sigue siendo apropiado para valores no objeto tanto en ARC como en MRC.

Question

Estoy navegando por el maravilloso blog mantenido por Scott Stevenson, y estoy tratando de comprender un concepto fundamental de Objective-C de asignar a los delegados la propiedad 'asignar' frente a 'retener'. Tenga en cuenta que ambos son iguales en un entorno recolectado de basura. Me preocupa sobre todo un entorno no basado en GC (p. Ej .: iPhone).

Directamente del blog de Scott:

"La palabra clave assign generará un setter que asigna el valor a la variable de instancia directamente, en lugar de copiarlo o retenerlo. Esto es mejor para tipos primitivos como NSInteger y CGFloat, u objetos que no son de su propiedad, como los delegados".

¿Qué significa que usted no posee directamente el objeto delegado? Normalmente retengo a mis delegados, porque si no quiero que se vayan al abismo, retener se encargará de eso por mí. Normalmente, elimino UITableViewController de su respectivo dataSource y también lo delego. También retengo ese objeto en particular. Quiero asegurarme de que nunca desaparezca, por lo que mi UITableView siempre tiene su delegado.

¿Alguien más puede explicar dónde / por qué estoy equivocado, entonces puedo entender este paradigma común en la programación de Objective-C 2.0 de usar la propiedad assign en los delegados en lugar de retener?

¡Gracias!




Una de las razones detrás de esto es evitar los ciclos de retención. Solo para evitar el escenario donde A y B ambos objetos se referencian entre sí y ninguno de ellos se libera de la memoria.

Acutally assign es mejor para tipos primitivos como NSInteger y CGFloat, u objetos que no son de su propiedad directamente, como los delegados.




Links