ios ios5 automatic-ref-counting weak-references strong-references

ios - débil o fuerte para IBOutlet y otro



ios5 automatic-ref-counting (2)

Esta pregunta ya tiene una respuesta aquí:

Cambié mi proyecto a ARC, y no entiendo si tengo que usar strong o weak para IBOutlets. Xcode hace esto: en el constructor de interfaces, si creamos un UILabel por ejemplo y lo conecto con el editor asistente a mi ViewController , crea esto:

@property (nonatomic, strong) UILabel *aLabel;

Utiliza el strong , en su lugar, leí un tutorial en el sitio web RayWenderlich que dice esto:

Pero para estas dos propiedades en particular, tengo otros planes. En lugar de ser strong , los declararemos como weak .

@property (nonatomic, weak) IBOutlet UITableView *tableView; @property (nonatomic, weak) IBOutlet UISearchBar *searchBar;

Weak es la relación recomendada para todas las propiedades de salida . Estos objetos de vista ya son parte de la jerarquía de vista del controlador de vista y no necesitan ser retenidos en otro lugar. La gran ventaja de declarar que sus puntos de venta son weak es que le ahorra tiempo escribir el método viewDidUnload.

Actualmente, nuestra viewDidUnload tiene este aspecto:

- (void)viewDidUnload { [super viewDidUnload]; self.tableView = nil; self.searchBar = nil; soundEffect = nil; }

Ahora puede simplificarlo a lo siguiente:

- (void)viewDidUnload { [super viewDidUnload]; soundEffect = nil; }

Así que use weak , en lugar de strong , y elimine el set en nil en la videDidUnload , en cambio Xcode use el strong , y use el self... = nil en viewDidUnload .

Mi pregunta es: ¿cuándo debo usar strong y cuándo weak ? También quiero utilizar para el destino de despliegue iOS 4, así que, ¿cuándo debo usar el unsafe_unretain ? ¿Alguien puede ayudarme a explicarme bien con un pequeño tutorial, cuando use strong , weak e unsafe_unretain con ARC?


Puede usar weak para objetos que están conectados a través de IBOutlets a objetos en IB porque en este caso los objetos estarán allí mientras la superview esté allí. Esto se debe a que la supervista tiene un fuerte puntero a sus subvistas.

Si el puntero que está definiendo es el único puntero a un objeto, debe declararlo como fuerte.

Si es un desarrollador registrado, le recomiendo que eche un vistazo a los videos de WWDC11 y WWDC12. Otro buen recurso es el podcast de desarrollo iOS de Stanford.


Una regla de oro

Cuando un padre tiene una referencia a un objeto hijo, debe usar una referencia strong . Cuando un niño tiene una referencia a su objeto principal, debe usar una referencia weak o una no unsafe_unretained (si la primera no está disponible). Un escenario típico es cuando tratas con delegados. Por ejemplo, un UITableViewDelegate no conserva una clase de controlador que contiene una vista de tabla.

Aquí un esquema simple para presentar los conceptos principales.

Supongamos que primero A, B y C son referencias strong . En particular, C tiene una strong referencia a su padre. Cuando obj1 se libera (en algún lugar), la referencia A ya no existe, pero tiene una fuga ya que hay un ciclo entre obj1 y obj2. Hablando en términos de conteos de retención ( solo para propósitos de explicación ), obj1 tiene un conteo de retención de 2 (obj2 tiene una referencia strong ), mientras que obj2 tiene un conteo de retención de 1. Si se libera obj1, su conteo de retención es ahora 1 y su método dealloc no es llamado. obj1 y obj2 aún permanecen en la memoria, pero nadie tiene una referencia a ellos: fuga .

En el contrato, si solo A y B son referencias strong y C está calificado como weak todo está bien. No tienes filtraciones De hecho, cuando se lanza obj1, también libera obj2. Hablando en términos de conteos de retención, obj1 tiene un conteo de retención de 1, obj2 tiene un conteo de retención de 1. Si se libera obj1, su conteo retenido es ahora 0 y se llama a su método dealloc . obj1 y obj2 se eliminan de la memoria.

Una sugerencia simple: comience a pensar en términos de gráfico de objetos cuando trabaje con ARC.

Sobre su primera pregunta, ambas soluciones son válidas cuando trata con XIB. En general, weak referencias weak se utilizan cuando se trata de ciclos de memoria. Con respecto a los archivos XIB, si usa strong necesita establecer nil en viewDidUnload ya que si no lo hace, en condiciones de poca memoria, podría causar pérdidas inesperadas. No los libera en dealloc porque ARC lo hará por usted. weak cambio, no necesita ese tratamiento ya que, cuando se destruye el objeto de destino, esos valores se establecen como nil automática. Ya no hay punteros colgantes.

Si está interesado, realmente le sugiero que lea friday-qa-2012-04-13-nib-memory-management por Mike Ash .

Sobre su segunda pregunta, si necesita soportar iOS 4, en lugar de weak , debe usar unsafe_unretained .

Dentro de SO hay muchas preguntas / respuestas. Aquí los principales:

¿Cómo reemplazo las referencias débiles cuando uso ARC y apunte a iOS 4.0?

¿Qué tipo de fugas evita o minimiza el conteo automático de referencias en Objective-C?

usando ARC, asignar calificador de por vida y inseguro_unretenido

strong / weak / retain / unsafe_unretained / assign

Espero que ayude.

Actualizar

Según el comentario de shaunlim, a partir de iOS 6 el método viewDidUnload está en desuso. Aquí realmente sugiero ver la respuesta de Rob: iOS 6: viewDidUnload migrate to didReceiveMemoryWarning? .