2012-06-20 10 views
9

Así que tuve un proyecto que admitía iOS 4, por lo que todos mis IBOutlets eran __unsafe_unretained incluso IBOutlets que estaban en el plumín pero fuera de la vista principal del controlador (Vista separada en el mismo plumín) y todo funcionó muy bien.Diferencias entre débil e inseguro_unretenido

Así que ha llegado el momento y ahora el cliente quiere apoyar solamente iOS 5 para que nuestro equipo cambiado todos los __unsafe_unretained IBOutlets para __weak IBOutlets pero ahora el IBOutlets que no están dentro de la vista principal se ponen a nil (excepto en viewdidload) por lo no podemos agregarlos más tarde.

Si lo pienso, tiene sentido porque si no hay vista (vista principal) que retiene esos IBOutlets, se deben desasignar y poner a cero (no sé si esa es la palabra correcta), entonces la solución es quitar el __weak de esos IBOutlets

Pero lo que no tiene sentido para mí es la razón por el diferente comportamiento entre unsafe_unretained y weak, en mi cabeza los unsafe_unretained los debe cancelar la asignación y cuando la aplicación intenta acceder a ellos, ellos deben apuntar a una referencia no válida y luego la aplicación debería bloquearse.

Pensé que unsafe__unretained era lo mismo que weak pero without the zeroing.

¿Falta algo aquí?

Gracias.

+4

Usted está en lo correcto. unsafe_unretained no anula la referencia. – Francesco

Respuesta

5

Pensé que unsafe__unretained era lo mismo que weak pero without the zeroing.

Sí, sí.

Cuando Cocoa carga la punta, crea todos los objetos liberados automáticamente, por lo que todavía están allí cuando se invoca viewDidLoad. Sin embargo, el grupo de autorrelease tiene una duración que finaliza cuando el control vuelve al ciclo de ejecución. En este punto, todos los objetos que no son propiedad de nada desaparecerán, por lo que cualquier salida débil se pondrá a cero en ese punto.

Para la mayoría de los puntos de venta, esto no es un problema porque los objetos en el NIB ya son generalmente propiedad de algo de todos modos. Entonces, por ejemplo, un botón en una vista es propiedad de su vista principal. Tener salidas fuertes que apunten a ese botón son, por lo tanto, exageradas o peores puede dar como resultado un ciclo de retención.

Objetos de nivel superior, obviamente, no tienen una vista principal para poseerlos, por lo que deben ser propiedad de otra cosa, p. un controlador o "Propietario del archivo". Si encuentra cosas que desaparecen, debe crear una IBOutlet fuerte en el propietario de File.

Para obtener más información, consulte Apple's docs.

+1

Eso tiene mucho sentido, y estoy completamente consciente de eso, pero mi pregunta es ¿por qué cuando uso inseguro_unretenido esos IBOutlets nunca se desasignan y puedo usarlos cada vez que lo desee (en el tiempo)? – Ecarrion

+0

@Ecarrion, en mi opinión, está ahí hasta el momento en que el trozo de memoria no se sobrescribe/sobrescribe. Y cuando se sobrescriba la aplicación obtiene un mal acceso. – MANN

0

Tiene razón, la aplicación se bloqueará cuando intente acceder a objetos desasignados a través de sus referencias __unsafe_unretained obsoletas.

La razón por la que no es muy probable porque los objetos están siendo referenciados por alguna otra parte de su aplicación con referencias fuertes.

Trate de ejecutar con zombies habilitados, eso debería causar un bloqueo inmediato al eliminar referencias a los punteros presuntamente obsoletos.

1

Para futuros buscadores que se encuentren con esta pregunta, creo que la Stackoverflow answer de CRD a una pregunta similar puede explicar.Aunque el objeto ha sido desasignado, la memoria a la que hace referencia el puntero no retenido inseguro (que contiene los datos reales del objeto) no está necesariamente puesta a cero, por lo que parece que las cosas se comportan correctamente hasta que la memoria se reutiliza/modifica/pone a cero.