2012-10-09 35 views
9

Nunca he trabajado en proyectos que no estén basados ​​en ARC. Me encontré con un zombie en mi proyecto basado en ARC. Descubrí que era debido al ciclo de retención. Me pregunto qué es un ciclo de retención. PuedeRetener ciclo en ARC

¿Podría darme un ejemplo para el ciclo de retención?

+4

Un zombi no se produce debido a un ciclo de retener. – bbum

Respuesta

22

A retener ciclo es una situación cuando el objeto A conserva objeto B, y el objeto B retiene el objeto A al mismo tiempo *. Aquí está un ejemplo:

@class Child; 
@interface Parent : NSObject { 
    Child *child; // Instance variables are implicitly __strong 
} 
@end 
@interface Child : NSObject { 
    Parent *parent; 
} 
@end 

usted puede fijar un ciclo en el ARC retienen mediante el uso de __weak variables o weak propiedades para sus "enlaces de vuelta", es decir, enlaces para dirigir o padres indirecta, en una jerarquía de objetos:

@class Child; 
@interface Parent : NSObject { 
    Child *child; 
} 
@end 
@interface Child : NSObject { 
    __weak Parent *parent; 
} 
@end 


* Esta es la forma más primitiva de un ciclo de retención; puede haber una larga cadena de objetos que se retengan en un círculo.

+2

¿Perdirá el ciclo de retención la pérdida de memoria en ARC? – Raj

+0

@Raj ¡Absolutamente! Los ciclos de retención no son específicos de ARC, causarán pérdidas de memoria en escenarios ARC y no ARC. – dasblinkenlight

+0

Podríamos evitar que causen pérdidas de memoria, como he explicado en los comentarios a la respuesta de @ Simon_Germain. – trss

9

Esto es lo que es un ciclo de retención: cuando 2 objetos se mantienen una referencia el uno al otro y se retienen, crea un ciclo de retención ya que ambos objetos intentan retenerse entre sí, lo que hace imposible su liberación.

@class classB; 

@interface classA 

@property (nonatomic, strong) classB *b; 

@end 


@class classA; 

@interface classB 

@property (nonatomic, strong) classA *a; 

@end 

Para evitar retener ciclos con ARC, simplemente declarar uno de ellos con una referencia weak, así:

@property (nonatomic, weak) classA *a; 
+0

¿Imposible lanzar? Podría liberarse si tenemos cuidado de reasignar algún otro objeto para una de esas propiedades rompiendo la cadena ¿no? Estoy preguntando específicamente porque he oído que es imposible lanzar muchas veces. – trss

+0

El encabezado "Evitar retener ciclos regla # 4: utilizar métodos" cerrar "para romper ciclos" en http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html parece confirmar que es posible romper los ciclos de retención. Definitivamente es mejor evitarlo, pero si crea complejidad, de lo contrario, aún podría usarse pero con cuidado para romperlo antes de que creen una fuga de memoria, evitando así la fuga. – trss

+0

Imposible podría ser un poco exagerado, pero digamos que no es exactamente trivial. Nada es imposible. –

Cuestiones relacionadas