web-dev-qa-db-fra.com

Comprendre le cycle de conservation en profondeur

Disons que nous avons trois objets: un grand-parent, un parent et un enfant. Le grand-parent conserve le parent, le parent conserve l'enfant et l'enfant conserve le parent. Le grand-parent libère le parent.

Que se passera-t-il dans ce cas?

52
Tariq

À moins qu'il n'y ait une autre référence au parent ou à l'enfant, ils deviennent tous deux orphelins. Mais le cycle de rétention entre le parent et l'enfant empêche la libération et la perte de mémoire.

Un enfant ne devrait jamais garder un parent. Si quoi que ce soit, utilisez une référence faible chez l'enfant pour conserver une référence au parent.

69
rmaddy

Le cycle de rétention est la condition Lorsque 2 objets gardent une référence l'un par rapport à l'autre et sont conservés, cela crée un cycle de rétention car les deux objets essaient de se conserver, ce qui rend impossible leur libération.

Ici, le "grand-parent" conserve le "parent" et le "parent" conserve "l'enfant" alors que "l'enfant" conserve le "parent". Ici, un cycle de rétention est établi entre le parent et l'enfant. Après avoir libéré le grand-parent, le parent et l'enfant deviennent orphelins, mais le nombre de parents retenus ne sera pas nul car il est conservé par l'enfant et provoque donc un problème de gestion de la mémoire.

Il y a deux solutions possibles:

1) Utilisez un pointeur faible vers le parent, c'est-à-dire qu'un enfant doit utiliser une référence faible vers le parent, qui n'est pas conservée.

2) Utilisez des méthodes de "fermeture" pour briser les cycles de rétention.

http://www.cocoawithlove.com/2009/07/rules-to-avoid-retain-cycles.html

26
Aritra Das

Dans un cas simple, considérons deux objets A et B où A crée et conserve B. Lorsque A est créé, il crée B. Lorsque celui qui a créé A le libère finalement, le nombre de retenues de A tombe à zéro et il est désalloué. Si la méthode de désallocation de A appelle la libération sur B, le nombre de retenues de B tombe également à zéro et il est également désalloué. [Cela suppose que personne d'autre n'a conservé A ou B, car je garde les choses simples.]

Mais que se passe-t-il si B a besoin d'une référence à A et qu'il conserve A? Celui qui a créé A pourrait le libérer. Mais puisque B a également conservé A, le nombre de retenues de A n'ira pas à zéro. De même, puisque A conserve B, le nombre de retenues de B n'ira pas non plus à zéro. Aucun ne sera désalloué. Même si B appelle la méthode de libération de A dans son propre dealloc, cela n'a pas d'importance, car cette méthode ne sera jamais appelée.

À ce stade, vous avez une fuite de mémoire, car vous n'avez aucune référence à A ou B même si les deux existent toujours. Si A ou B fait quelque chose de gourmand en processeur, vous risquez également de perdre du temps CPU vers des objets indésirables.

Dans votre cas, A est parent et B est enfant et quiconque a créé A est grand-parent.

10
RMDeveloper

Un cycle de rétention est une boucle qui se produit lorsque l’objet A conserve l’objet B et que l’objet B conserve l’objet A. Dans ce cas, si l’un ou l’autre des objets est libéré:

  • L'objet A ne sera pas désalloué car l'objet B en contient une référence (conserver le nombre> 0).
  • L'objet B ne sera jamais désalloué tant que l'objet A aura une référence (conserver le compte> 0).
  • Mais l'objet A ne sera jamais désalloué car l'objet B en contient une référence (conserver le nombre> 0).
  • jusqu'à l'infini

Ainsi, ces deux objets resteront simplement en mémoire pendant toute la durée de vie du programme, même s'ils doivent, si tout fonctionnait correctement, être désalloués.

5
Aamir

Lorsque les grands-parents relâchent le parent, le parent est toujours en vie car l'enfant conserve le parent.

4
Danyun Liu

Grand-parent: John Parent: Ted Enfant: Mary

Voici mon exemple utilisant un appel téléphonique pour l'illustration:

  • John appelle Ted et veut faire une conférence téléphonique avec Mary.

  • Ted dit à John: "Accrochez-vous et je vais appeler Mary"

  • Ted laisse John en attente et appelle Mary qui répond rapidement au téléphone.

  • Mary dit à Ted: "Fusionne mon appel avec John et je ne raccrocherai pas avant d'avoir fini"

  • Ted, n'ayant pas eu de nouvelles de John depuis un moment, quitte l'appel pour faire autre chose.

  • John va fusionner les appels avec Ted et Mary puis meurt soudainement.

  • Mary est coincée avec John mais ne raccrochera jamais car John ne reviendra pas!

1
paul_f

Cycle de conservation est la condition lorsque 2 objets gardent une référence l'un à l'autre et sont conservés, il crée un cycle de conservation puisque les deux objets essayez de conserver les uns des autres, ce qui rend impossible la libération.


Exemple: Une personne vit dans un département, un département a une personne.

@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

Ensuite, appelez-le comme ceci:

- (void)viewDidLoad {
    [super viewDidLoad];
    Person * person = [[Person alloc] init];
    Department * department = [[Department alloc] init];
    person.department = department;
    department.person = person;
}

Vous ne verrez pas le journal de dealloc, c'est le cercle de retenue.

1
delarcomarta

Étant donné que l'objet P a retenueCount de 1, lorsqu'il est libéré, son retenueCount passe à 0, et sa méthode dealloc est appelée; Cela appelle à son tour la libération sur l'objet C, dont le nombre de retenues passe également à 0; et sa méthode dealloc est appelée.

Les deux objets P et C seront libérés.

Lorsque la méthode dealloc de l'objet C est appelée, à son tour, la libération de l'objet GP est appelée, mais comme GP contient un nombre de retenues de 2, le nombre de retenues est décrémenté à 1 et il continue de traîner.

0
Shalab

Le cycle de conservation est une condition de blocage. Exemple réel de cycle de conservation: si deux objets se tiennent une référence et qu'aucun autre objet n'est libéré.

Exemple: jeu de rami

0
Saurabh Kumar Sharma