2012-08-24 21 views
6

Soy nuevo en el desarrollo de iphone. Estoy usando ARC para mi proyecto. Por lo que entendí al usar ARC, no tenemos que liberar ningún objeto manualmente. Pero, he observado en algunos lugares, las personas establecen explícitamente su objeto a cero en ViewDidUnload, incluso después de usar ARC.Propiedades débiles y fuertes en -viewDidUnload bajo ARC

Por ejemplo, en el archivo .h que tienen algo como esto:

@property (unsafe_unretained, nonatomic) IBOutlet MKMapView *mapViewOutlet; 
@property (unsafe_unretained, nonatomic) IBOutlet UIToolbar *toolBar; 
@property (strong,nonatomic) NSMutableArray *dataArray; 

Y .m de la siguiente manera:

- (void)viewDidUnload 
{ 
    [self setMapViewOutlet:nil]; 
    [self setToolBar:nil]; 
    [super viewDidUnload]; 
    self.dataArray=nil; 
} 

Mi pregunta es, ¿es realmente necesario especificar explícitamente nula en ViewDidUnload incluso bajo ARC?

Respuesta

10

El objetivo del método viewDidUnload es liberar datos que realmente no necesita, para liberar memoria. Leer the documentation:

Cuando una condición de memoria baja se produce y no se necesitan puntos de vista del controlador de vista actual, el sistema puede optar por eliminar los puntos de vista de memoria. Se llama a este método después de que la vista del controlador de la vista se haya liberado y es su oportunidad de realizar cualquier limpieza final. Si su controlador de vista almacena referencias separadas a la vista o sus subvistas , debe utilizar este método para liberar esas referencias. Usted también puede usar este método para eliminar referencias a cualquier objeto que haya creado para admitir la vista, pero que ya no sean necesarios ahora que la vista ha desaparecido. No debe utilizar este método para liberar datos de usuario o cualquier otra información que no se pueda recrear fácilmente.

Así se está configurando las propiedades a nil con el fin de liberar los objetos ahora y ayudar al sistema para liberar algo de memoria. Pero, por supuesto, esto depende del tipo de propiedad: las propiedades fuertes son "tuyas" y solo tú puedes decidir si liberarlas ahora (estableciendo en nil) o no. Las propiedades débiles ya podrían ser nil, por ejemplo, si apuntaban a algunas vistas que se lanzaron con la vista principal. Y las propiedades unsafe_unretained son una bestia especial. El objeto al que apuntan puede que ya se haya liberado, pero eso no significa que se haya configurado en nil automáticamente. Por lo tanto, debe usar uno de los tipos de propiedad "más segura" (fuerte/débil) o establecer las propiedades inseguras en nil aquí, para asegurarse de que no utilizará el objeto liberado más adelante. No hay reglas duras en este caso, debes pensar en la situación y lo que significa para las distintas propiedades.

Por cierto, viewDidUnload se está desaprobando en iOS 6, donde ya no se lanzan vistas en condiciones de baja memoria. Aún recibe la devolución de llamada didReceiveMemoryWarning, por lo que puede liberar algunos recursos allí si lo desea. De nuevo, le sugiero que lea la documentación y realice algunas pruebas para ver qué sucede y decidir qué debe hacer.

+0

Pero, incluso si no configuro nada, el sistema liberará la memoria automáticamente en ARC ¿verdad? – Raj

+0

Eventualmente, sí. Es difícil (er) crear una fuga bajo ARC. Depende de usted decidir si puede ayudar al sistema liberando una gran cantidad de memoria cuando su aplicación recibe la advertencia de memoria. – zoul

+0

Ok. Aceptaré esta respuesta. – Raj

2

Cuando está utilizando unsafe_unretained, debe asignarla a cero, ya que no se le asignará a cero de manera implícita, en donde es el caso de referencia débil será asignada a nil implícitamente. Así que para evitar cualquier referencia que cuelgue debe asignar a nil en caso de que no se haya conservado.

+0

Sí, incluso yo pensé lo mismo. Pero he visto en algunos lugares incluso las referencias débiles establecidas en nil. En mi pregunta, puede ver incluso el conjunto de referencia fuerte en nil. – Raj

3

ARC solo lanzará propiedades que no tengan una referencia fuerte a un objeto. En su caso, estas son todas referencias sólidas, por lo que se mantendrán a menos que se establezcan explícitamente en cero.

El método viewDidUnload no significa que su UIViewController se eliminó de la memoria, simplemente significa que sus vistas se eliminaron de la memoria (iOS Developer - ViewController lifecycle).

En este caso, su UIViewController permanece en la memoria y, por lo tanto, también sus propiedades, a menos que se configuren explícitamente como nulas.

+0

En mi caso, no son todas las referencias fuertes. Para su información, débil no es compatible con IOS4, en su lugar usamos inseguro-no retenido, lo que puede crear un momento colgando punteros. La funcionalidad en ambos casos es la misma – Raj

+0

Correcto, lo siento, estaba buscando la palabra clave débil (ahora solo se está desarrollando para iOS5). – Resh32

+0

y, por lo que yo sé, ARC llamará automáticamente a dealloc por las referencias fuertes. Por lo tanto, no tenemos que establecerlas en nil explícitamente. En cuanto a las referencias débiles, lo configuramos en cero, para evitar punteros colgantes que puede ser posible en algunos casos – Raj

Cuestiones relacionadas