class — définition, concepts clés et principe de fonctionnement en Swift

Auteur : IT Sectr Publié le : 2026-06-17 Temps de lecture : 8 min

Class est un type par référence (reference type) dans le langage Swift, dont les instances sont passées par référence plutôt que copiées lors de l'affectation. Contrairement aux structures, les classes prennent en charge l'héritage, la déinitialisation et le comptage automatique des références ARC pour la gestion de la mémoire. Selon le Swift Programming Language Guide, 2026, class est nécessaire pour travailler avec les frameworks d'UI d'Apple (UIKit, AppKit) et implémenter des motifs nécessitant une identité partagée d'objet. Le choix entre class et struct est l'une des décisions architecturales clés en Swift.

Points essentiels

  • Class — type par référence en Swift où une variable stocke une référence à un objet dans le tas, et non la valeur elle-même.
  • Héritage — les classes peuvent hériter des propriétés et méthodes d'une classe parente et les redéfinir avec override.
  • ARC — le comptage automatique des références libère la mémoire lorsqu'il ne reste plus de références fortes à un objet.
  • Deinit — méthode spéciale appelée avant la libération d'un objet pour nettoyer les ressources.
  • Identité — les opérateurs === et !== vérifient si deux variables référencent la même instance de classe.

Qu'est-ce que class en Swift ?

Class — un type composé par référence en Swift qui regroupe propriétés et méthodes en une entité unique avec prise en charge de l'héritage et de la répartition dynamique. Contrairement à struct, une instance de classe est créée dans le tas, et une variable stocke une référence à cette instance, et non les données elles-mêmes.

Lorsque vous assignez une variable de classe à une autre variable, toutes deux référencent le même objet en mémoire. Les modifications via une référence sont visibles via l'autre — c'est une propriété fondamentale des types par référence, utilisée dans les motifs de délégation, d'observation et d'état partagé.

Selon la Documentation Apple Swift, les classes sont le seul moyen de travailler avec UIKit et AppKit, où tous les composants d'UI héritent de UIView et UIViewController. De plus, les classes sont nécessaires pour implémenter des motifs qui nécessitent l'identité d'objet (deux références vers un objet) et une durée de vie contrôlée.

Class comme type par référence

La sémantique de type par référence — la propriété clé des classes. Lors de l'assignation d'une classe à une nouvelle variable, Swift copie la référence, pas les données. Toutes les variables qui référencent la même instance voient son état actuel et peuvent le modifier. Ce comportement diffère fondamentalement des types par valeur, où chaque variable obtient une copie indépendante.

swift
// Exemple de sémantique de type par référence
class User {
    var name: String
    init(name: String) { self.name = name }
}

let user1 = User(name: "Alice")
let user2 = user1           // user2 — même référence
user2.name = "Bob"

print(user1.name)               // "Bob" — modifié via user2 !

// Vérification d'identité avec l'opérateur ===
print(user1 === user2)          // true — même objet

Les opérateurs === (identité) et !== vérifient si deux variables référencent la même instance de classe. Cela diffère de == (égalité), qui compare les valeurs des propriétés. L'opérateur === n'est pas disponible pour struct — les types par valeur n'ont pas d'identité.

Héritage des classes

Héritage — un mécanisme par lequel une classe peut adopter les propriétés et méthodes d'une classe parente. En Swift, une classe ne peut hériter que d'un seul parent (héritage simple), mais peut implémenter plusieurs protocoles. Le mot-clé override permet de redéfinir une méthode ou propriété héritée.

Classe de base et sous-classe

Toute classe qui n'hérite pas d'une autre classe devient automatiquement une classe de base (à ne pas confondre avec NSObject). Une sous-classe spécifie le parent avec deux-points après son nom. Si une sous-classe redéfinit une méthode du parent, elle doit appeler super.méthode() pour préserver le comportement du parent — c'est une exigence du compilateur.

Classe finale

Le mot-clé final avant class empêche l'héritage. Le compilateur peut optimiser les appels de méthodes d'une classe finale via une répartition statique, améliorant ainsi les performances. Utilisez final pour les classes non destinées à l'extension — cela documente votre intention et accélère le code.

swift
// Exemple d'héritage de classes en Swift
class Vehicle {
    var speed: Double = 0

    func description() -> String {
        "Speed: \(speed) km/h"
    }
}

// Car hérite de Vehicle
class Car: Vehicle {
    var brand: String = "Unknown"

    override func description() -> String {
        "\(brand) - \(speed) km/h"
    }
}

// Classe finale — empêche l'héritage
final class ElectricCar: Car {
    var batteryLevel: Double = 100
}

let tesla = ElectricCar()
tesla.brand = "Tesla"
tesla.speed = 120
print(tesla.description())  // "Tesla - 120.0 km/h"

L'héritage est un mécanisme puissant mais responsable. Les hiérarchies profondes (plus de 5 niveaux) compliquent la maintenance et les tests. Pour la réutilisation fonctionnelle sans héritage, utilisez des protocoles avec extension et la programmation orientée protocole — une approche qu'Apple promeut comme alternative aux hiérarchies de classes profondes.

Déinitialisation et gestion de la mémoire

Swift utilise ARC (Comptage Automatique des Références) pour la gestion de la mémoire des classes. Chaque instance de classe possède un compteur de références fortes. Lorsqu'une nouvelle référence forte est créée, le compteur augmente ; lorsqu'elle est détruite, il diminue. Lorsque le compteur atteint zéro, la mémoire est libérée.

Deinit

Deinit — méthode appelée automatiquement avant la libération d'une instance de classe. Elle libère des ressources : ferme des fichiers, se désabonne des notifications, arrête des minuteries. Deinit n'est disponible que pour les classes — les structures et énumérations ne l'ont pas.

Références faibles et non possédées

Pour prévenir les cycles de références fortes (retain cycles), Swift fournit des références weak et unowned. Weak est une référence optionnelle qui devient automatiquement nil lorsque l'objet est libéré. Unowned n'est pas optionnelle mais référence un objet garanti de vivre plus longtemps que le contexte actuel. Un cycle de rétention typique se produit dans une relation parent-enfant : l'enfant maintient une référence forte au parent.

swift
// Exemple d'ARC et de référence faible
class Parent {
    var name: String
    var child: Child?

    init(name: String) { self.name = name }
    deinit { print("\(name) désalloué") }
}

class Child {
    var name: String
    weak var parent: Parent?   // weak empêche le cycle de rétention

    init(name: String) { self.name = name }
    deinit { print("\(name) désalloué") }
}

var parent: Parent? = Parent(name: "Anna")
parent?.child = Child(name: "Mia")
parent?.child?.parent = parent

parent = nil  // Les deux objets désalloués !
// Sans weak, cela créerait un cycle de rétention

Utilisez toujours weak pour les références d'un objet enfant vers le parent et pour les listes de capture dans les closures. Utilisez unowned uniquement lorsque vous êtes sûr que l'objet survivra au contexte actuel — une utilisation incorrecte d'unowned peut provoquer un crash lors de l'accès à une mémoire libérée.

Class vs Struct : différences clés

Le choix entre class et struct est une décision architecturale qui affecte les performances, la sécurité des threads et la conception d'API. Considérez le tableau des différences clés pour prendre la bonne décision dans chaque cas.

Caractéristiqueclassstruct
TypeType par référenceType par valeur (copie)
MémoireTas + ARCPile / inlined
HéritagePrend en charge (parent unique)Ne prend pas en charge
DeinitDisponibleNon disponible
Identité (===)Prend en chargeNe prend pas en charge
MutatingNon requis (toujours mutating)Uniquement avec mutating
Init memberwiseNon généréGénéré automatiquement
Sécurité des threadsNon garantie (état partagé)Garantie (copie)

Utilisez les classes lorsque vous avez besoin d'identité partagée (plusieurs parties du code travaillant avec un objet), d'héritage ou d'interaction avec l'environnement d'exécution Objective-C. Pour tout le reste, les structures sont préférables — elles sont plus rapides, plus sûres dans le code multithread et ne nécessitent pas de gestion de la mémoire.

Quand utiliser class en Swift

Malgré la recommandation d'Apple d'utiliser struct par défaut, les classes sont nécessaires dans plusieurs scénarios spécifiques. Examinons chacun avec des exemples pratiques.

Composants UIKit et AppKit

Tous les composants d'UI sur iOS et macOS sont des classes qui héritent de UIView (iOS) ou NSView (macOS). Vous ne pouvez pas remplacer UIViewController par une struct — il nécessite l'héritage et deinit pour libérer les ressources. Lorsque vous travaillez avec UIKit, utilisez des classes pour les contrôleurs, les vues et leurs délégués.

Singleton et état partagé

Le motif Singleton (une instance de classe pour toute l'application) nécessite une sémantique de référence. Les gestionnaires : NetworkManager, SettingsManager, AnalyticsService — sont généralement implémentés comme des classes avec une propriété statique partagée. Les structures ne conviennent pas car chaque copie serait une instance indépendante.

Injection de dépendances et objets par référence

Lorsqu'un objet doit être la source unique de vérité et est passé entre modules par référence — utilisez class. Cela s'applique à la gestion d'état, où la modification d'un objet à un endroit doit être visible dans tous les composants dépendants. Pour ObservableObject dans SwiftUI, les classes sont obligatoires.

swift
// ObservableObject — class requise pour SwiftUI
import SwiftUI

class AppViewModel: ObservableObject {
    @Published var isLoggedIn: Bool = false
    @Published var username: String = ""

    func login(user: String) {
        isLoggedIn = true
        username = user
    }
}

// Utilisation dans une vue SwiftUI
struct ContentView: View {
    @StateObject var viewModel = AppViewModel()

    var body: some View {
        Text(viewModel.isLoggedIn ? "Bienvenue" : "Connexion")
    }
}

Règle : si un objet doit avoir une identité (deux références -> un objet), être une instance unique ou fonctionner avec UIKit/Objective-C — choisissez class. Si un objet contient simplement des données — choisissez struct.

Questions fréquentes

Qu'est-ce que class en Swift ?

Class est un type par référence en Swift qui prend en charge l'héritage, la déinitialisation et l'ARC pour la gestion de la mémoire. Les instances de classe sont stockées dans le tas et les variables contiennent une référence à l'objet, pas sa copie.

En quoi class diffère-t-il de struct en Swift ?

Class — type par référence (passé par référence), prend en charge l'héritage et deinit. Struct — type par valeur (copié), ne prend pas en charge l'héritage, mais implémente des protocoles et obtient automatiquement un init memberwise. Swift recommande struct comme type par défaut.

Qu'est-ce que l'ARC en Swift ?

ARC (Comptage Automatique des Références) — un mécanisme de gestion de la mémoire pour les classes Swift. Chaque instance possède un compteur de références fortes. Lorsque le compteur atteint zéro, la mémoire est libérée. Les références weak et unowned empêchent les cycles de rétention entre les objets.

Qu'est-ce que deinit en Swift ?

Deinit — une méthode de classe appelée automatiquement avant la libération de sa mémoire. Utilisée pour fermer des fichiers, se désabonner des notifications et autres opérations de nettoyage. Deinit n'est disponible que dans les classes — les structures ne l'ont pas.

Quand utiliser class en Swift ?

Utilisez class pour les composants d'UI UIKit/AppKit, le singleton, ObservableObject dans SwiftUI, les objets avec identité partagée (délégué, observateur) et lors du travail avec l'environnement d'exécution Objective-C. Pour les modèles de données, DTO et configurations, struct est préférable.

Résumé

  • Class est un type par référence en Swift avec une sémantique de passage par référence : toutes les variables pointant vers un objet voient son état actuel et peuvent le modifier.
  • ARC gère la mémoire des classes via le comptage des références fortes ; weak et unowned empêchent les cycles de rétention dans les relations parent-enfant et les closures.
  • Héritage permet aux classes de réutiliser et de redéfinir le comportement du parent, mais les hiérarchies profondes (plus de 5 niveaux) compliquent la maintenance du code.
  • Deinit s'exécute lorsqu'un objet est libéré et est nécessaire pour libérer les ressources — fichiers, minuteries, abonnements NotificationCenter.
  • UIKit et AppKit nécessitent des classes pour tous les composants d'UI — UIView, UIViewController, leurs délégués et sources de données.
  • ObservableObject dans SwiftUI — class est obligatoire car SwiftUI suit les modifications via @Published et @StateObject par référence.
  • Apple recommande struct comme type par défaut pour les nouveaux types de données — n'utilisez class que lorsque l'identité, l'héritage ou l'intégration Objective-C est nécessaire.

Nous développerons une application mobile clé en main

IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.

Discuter du projet

Lisez aussi