Sobes.tech
Intern

Qu'est-ce qu'un ramasse-miettes (garbage collector) ?

sobes.tech IA

Réponse de l'IA

Sur iOS, il n'y a pas de ramasse-miettes traditionnel. À la place, le mécanisme de Référence Automatique (ARC) est utilisé.

  • Mécanisme automatique : ARC compte automatiquement les références fortes aux objets.
  • Libération de mémoire : Lorsque le nombre de références fortes à un objet atteint zéro, ARC libère la mémoire allouée.
  • Prévention des fuites : L'utilisation correcte des références fortes, faibles et non possédées (unowned) permet d'éviter les fuites de mémoire et les cycles de références.

Types de références dans ARC :

  • Fort (strong): Augmente le compteur de références. C'est la valeur par défaut.
  • Faible (weak): N'augmente pas le compteur de références. Devient automatiquement nil lors de la désallocation de l'objet. Utilisé pour prévenir les cycles de références fortes. Déclaré comme un type optionnel.
  • Non possédé (unowned): N'augmente pas le compteur de références. Il est garanti que l'objet référencé existe pendant toute la durée de vie de la référence non possédée. N'est pas optionnel. Utilisé lorsque deux objets ont une relation forte mutuelle, mais qu'un d'eux a une durée de vie plus courte.

Avantages de ARC :

  • Prédictibilité : La libération de mémoire se produit de manière déterministe, dès que l'objet n'est plus utilisé.
  • Performance : Il n'y a pas de coûts supplémentaires pour un ramasse-miettes en arrière-plan, qui pourrait causer des pauses.
  • Simplicité : Le développeur n'a pas besoin de gérer manuellement la mémoire dans la plupart des cas, mais doit comprendre les principes de comptage de références pour éviter les fuites.

Exemple de cycle de références fortes :

class Person {
    let name: String
    var apartment: Apartment? // référence forte à Apartment

    init(name: String) { self.name = name }
    deinit { print("\(name) est en train d'être désinitialisé") }
}

class Apartment {
    let unit: String
    weak var tenant: Person? // référence faible à Person pour prévenir le cycle

    init(unit: String) { self.unit = unit }
    deinit { print("Appartement \(unit) est en train d'être désinitialisé") }
}

var john: Person?
var unit4A: Apartment?

john = Person(name: "John Appleseed")
unit4A = Apartment(unit: "4A")

john!.apartment = unit4A
unit4A!.tenant = john // L'utilisation de weak ici est critique

john = nil
unit4A = nil
// Sans tenant weak : John et l'appartement ne seraient pas désinitialisés.
// Avec tenant weak : John et l'appartement sont désinitialisés correctement.