ios - tesis - Entender retener el ciclo en profundidad
tesis sobre youtube pdf (7)
Digamos que tenemos tres objetos: un abuelo, padre e hijo. El abuelo retiene al padre, el padre retiene al hijo y el hijo retiene al padre. El abuelo libera al padre.
¿Qué pasará en este caso?
A menos que haya alguna otra referencia al padre o al niño, ambos quedarán huérfanos. Pero el ciclo de retención entre el padre y el hijo evita que se libere y se convierte en memoria desperdiciada.
Un niño nunca debe retener a un padre. En todo caso, use una referencia débil en el niño para mantener una referencia al padre.
Como el objeto P tiene retainCount de 1, cuando se libera, su retainCount pasa a 0 y se llama a su método dealloc; Esto a su vez llama liberación en el objeto C, cuyo conteo de retención también va a 0; y se llama su método dealloc.
Ambos objetos P y C serán liberados.
Cuando se llama al método dealloc del objeto C, a su vez se invoca la liberación del objeto GP, pero como GP mantiene un conteo retenido de 2, el recuento retenido se reduce a 1, y continúa suspendido.
Cuando el abuelo libera al padre, el padre todavía está vivo mientras el niño retiene al padre.
El ciclo de retención es la condición Cuando dos objetos 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 que sea imposible liberarlos.
Aquí El "Abuelo" retiene al "padre" y "padre" retiene al "hijo", mientras que "hijo" retiene al "padre". Aquí se establece un ciclo de retención entre el padre y el hijo. Después de liberar al Abuelo, tanto el padre como el hijo quedan huérfanos pero el recuento retenido del padre no será cero ya que el niño lo retiene y por lo tanto causa un problema de administración de la memoria.
Hay dos soluciones posibles:
1) Use el puntero débil para el elemento primario, es decir, un elemento secundario debe usar una referencia débil al elemento primario, que no se conserva.
2) Use métodos "cercanos" para romper los ciclos de retención.
http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html
En un caso simple, considere dos objetos A y B donde A crea y retiene B. Cuando A se crea, crea B. Cuando quien creó A finalmente lo libera, el conteo de retención de A cae a cero y se desasigna. Si el método dealloc de A llama a liberar B, el recuento de retención de B también se reduce a cero y también se desasigna. [Esto supone que nadie más ha conservado A o B, porque estoy manteniendo las cosas simples.]
Pero, ¿qué sucede si B necesita una referencia de vuelta a A, y retiene A? Quien creó A podría lanzarlo. Pero como B también retuvo A, el conteo de retención de A no irá a cero. Del mismo modo, ya que A conserva B, el conteo de retención de B tampoco irá a cero. Ninguno será desasignado. Incluso si B llama al método de publicación de A en su propio trato, no importa, porque ese método nunca se llamará.
En este punto, tiene una pérdida de memoria, porque no tiene ninguna referencia a A o B, aunque ambos todavía existen. Si A o B están haciendo algo con un procesador intensivo, es posible que también esté perdiendo tiempo de CPU en objetos no deseados.
En su caso A es padre y B es hijo y quien creó A es abuelo.
Un ciclo de retención es un ciclo que ocurre cuando el Objeto A conserva el Objeto B, y el Objeto B retiene el Objeto A. En esa situación, si cualquiera de los objetos se libera:
- El objeto A no se desasignará porque el Objeto B contiene una referencia (retenga el recuento> 0).
- El Objeto B no será desasignado siempre que el Objeto A tenga una referencia (retenga el recuento> 0).
- Pero el Objeto A nunca será desasignado porque el Objeto B contiene una referencia (retenga conteo> 0).
- hasta el infinito
Por lo tanto, esos dos objetos se quedarán en la memoria durante la vida útil del programa aunque deberían desasignarse, si todo funcionara correctamente.
El Ciclo de retención es la condición en la que dos objetos 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.
Ejemplo: una persona vive en un departamento, un departamento tiene una persona.
@class Department;
@interface Person:NSObject
@property (strong,nonatomic)Department * department;
@end
@implementation Person
-(void)dealloc{
NSLog(@"dealloc person");
}
@end
@interface Department: NSObject
@property (strong,nonatomic)Person * person;
@end
@implementation Department
-(void)dealloc{
NSLog(@"dealloc Department");
}
@end
Entonces llámalo así:
- (void)viewDidLoad {
[super viewDidLoad];
Person * person = [[Person alloc] init];
Department * department = [[Department alloc] init];
person.department = department;
department.person = person;
}
No verá el registro dealloc, este es el círculo de retención.