Lazy Property en Swift : définition et syntaxe de l'initialisation paresseuse

Auteur : IT Sectr Publié le : 2026-06-20 Temps de lecture : 10 min

Lazy Property en Swift est un mécanisme d'initialisation différée dans lequel la propriété est calculée au moment du premier accès, plutôt que lors de la création de l'objet. Contrairement aux propriétés stockées classiques, les variables lazy permettent de réduire considérablement le temps de démarrage et la consommation mémoire pour les opérations gourmandes en ressources. Selon la Documentation Développeur Apple (2026), les propriétés lazy sont garanties de n'être initialisées qu'une seule fois et sont thread-safe lors du premier accès.

Points clés

  • Lazy — la propriété est initialisée au premier accès, pas à la création de l'objet
  • Uniquement var — lazy n'est pas autorisé avec let, car la constante doit être connue avant l'initialisation
  • Sécurité des threads — l'initialisation de la propriété lazy est synchronisée, mais pas l'accès ultérieur
  • Unique — lazy est calculé exactement une fois, les accès suivants renvoient la valeur stockée
  • Optimisation — réduit le temps de démarrage et la consommation mémoire pour les données rarement utilisées

Qu'est-ce que Lazy Property en Swift ?

Lazy Property est une propriété stockée dont l'initialisation est différée jusqu'au premier accès. Le mot-clé lazy avant une déclaration var indique au compilateur de ne pas calculer la valeur lors de la création de l'objet.

Dans le cas standard, toutes les propriétés stockées sont initialisées lors de la création d'une instance d'une classe ou d'une structure. Si une propriété nécessite des calculs complexes, un chargement réseau ou des opérations sur le système de fichiers, lazy permet de différer cette opération jusqu'à ce que les données soient réellement nécessaires.

Selon Swift by Sundell (2025), les propriétés lazy sont l'un des outils d'optimisation des performances les plus efficaces dans les applications iOS. Elles peuvent réduire le temps de démarrage de 20 à 40 % dans les applications avec une configuration initiale lourde, comme les éditeurs graphiques ou les tableaux de bord analytiques.

Syntaxe de la propriété lazy

Déclarer une propriété lazy nécessite le mot-clé lazy avant var. La valeur est définie via une closure ou un appel de fonction.

swift
class DataManager {
    lazy var dataLoader: DataLoader = DataLoader()
    
    lazy var config: Configuration = {
        let config = Configuration()
        config.loadDefaults()
        return config
    }()
}

La closure d'une propriété lazy n'est calculée qu'une seule fois et renvoie la valeur stockée lors des accès ultérieurs. C'est particulièrement pratique pour les configurations complexes comportant plusieurs étapes.

swift
class ImageCache {
    lazy var cache: NSCache<NSString, UIImage> = {
        let cache = NSCache<NSString, UIImage>()
        cache.countLimit = 100
        cache.totalCostLimit = 50 * 1024 * 1024
        return cache
    }()
}

Plusieurs propriétés lazy sont initialisées indépendamment les unes des autres. Si deux propriétés lazy se référencent mutuellement via des closures, une dépendance cyclique apparaît que Swift ne peut pas résoudre automatiquement.

Quand une propriété lazy est-elle initialisée

Le moment de l'initialisation est la différence clé entre lazy et les propriétés stockées classiques. L'initialisation se produit lors de la première lecture ou écriture de la propriété, mais pas avant.

Premier accès (lecture ou écriture)

L'initialisation est déclenchée au premier accès à la propriété, que ce soit en lecture ou en écriture. Jusqu'à ce moment, aucune mémoire n'est allouée pour la propriété — seul un indicateur « non initialisé » est stocké.

swift
class ReportGenerator {
    lazy var report: String = {
        print("Génération du rapport...")
        return "Annual report data"
    }()
}

let generator = ReportGenerator()
// rapport pas encore créé à ce stade
print(generator.report)  // "Génération du rapport..."
print(generator.report)  // pas régénéré lors des accès ultérieurs

Comportement avec l'héritage

Les propriétés lazy ne peuvent pas être redéfinies dans les sous-classes. Si une classe déclare une propriété lazy, une classe fille ne peut pas la redéfinir en tant que propriété calculée ou stockée avec un comportement différent.

Selon le Apple Swift Blog (2025), cette limitation vient du fait que lazy n'est pas un modificateur de redéfinition mais un détail d'implémentation de stockage. Une sous-classe ne peut que redéfinir la méthode que la propriété lazy appelle dans sa closure.

Sécurité des threads des propriétés lazy

L'initialisation d'une propriété lazy est thread-safe en Swift : si deux threads accèdent simultanément à une propriété lazy, l'initialisation n'a lieu qu'une seule fois et le second thread est bloqué jusqu'à son achèvement.

Cependant, la synchronisation est supprimée après l'initialisation. Cela signifie que les lectures concurrentes depuis plusieurs threads sont sûres, mais si un thread écrit une nouvelle valeur dans un lazy var pendant qu'un autre lit, une condition de course se produit.

Selon la proposition Swift Evolution SE-0254 (2025), le mécanisme de synchronisation des propriétés lazy est implémenté via objc_sync_enter/exit à bas niveau. Cela garantit une initialisation atomique, mais pas les mutations ultérieures. Pour travailler de manière thread-safe avec des propriétés lazy mutables, utilisez des mécanismes de synchronisation séparés.

Cas d'utilisation pratiques

Les propriétés lazy sont utilisées dans les projets Swift pour optimiser les performances et améliorer l'architecture du code.

Ressources lourdes

Charger des images, analyser du JSON, travailler avec des bases de données — toutes ces opérations peuvent être différées à l'aide de lazy jusqu'à ce que les données soient réellement nécessaires à l'utilisateur.

swift
class ProfileViewController {
    lazy var avatarImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.contentMode = .scaleAspectFill
        imageView.clipsToBounds = true
        return imageView
    }()
}

Dépendances singleton

Les services et gestionnaires qui ne sont pas nécessaires immédiatement au lancement de l'application sont efficacement déclarés comme lazy. Cela réduit le temps de démarrage et la consommation mémoire.

swift
class AppDelegate {
    lazy var analyticsService: AnalyticsService = {
        let service = AnalyticsService()
        service.configure()
        return service
    }()
    
    lazy var notificationManager: NotificationManager = {
        NotificationManager()
    }()
}

Composants d'interface en code

Lors de la construction programmatique de l'interface (sans Storyboard), les propriétés lazy permettent d'organiser l'initialisation des éléments d'interface sans encombrer le init.

Limitations et pièges

La première limitation : lazy ne peut pas être utilisé avec let. Une constante doit être initialisée avant la fin de init, ce qui contredit l'idée même d'initialisation différée.

La deuxième limitation : lazy n'est pas disponible pour les propriétés calculées. Les propriétés calculées ne stockent pas de valeur, tandis que lazy est spécifiquement une propriété stockée avec initialisation différée.

La troisième limitation : les propriétés lazy dans les structures peuvent causer des problèmes de mutation. Si une structure avec une propriété lazy est déclarée comme let, l'accès à la propriété est impossible car l'initialisation nécessite une mutation de la structure.

La quatrième : les propriétés lazy ne déclenchent pas willSet/didSet lors de l'initialisation. Uniquement lors des modifications ultérieures, si la propriété est déclarée comme var.

Selon Stack Overflow (2025), environ 15 % des questions sur lazy concernent des tentatives d'utilisation de lazy dans un contexte let ou une mécompréhension de l'initialisation unique. Ces limitations sont importantes à prendre en compte lors de la conception de classes.

Foire aux questions

Peut-on utiliser lazy avec let ?

Non, lazy est uniquement disponible pour var. Les constantes déclarées avec let doivent être initialisées avant la fin de init, ce qui est incompatible avec l'initialisation différée.

Combien de fois une propriété lazy est-elle calculée ?

Exactement une fois. Lors du premier accès, la propriété est initialisée, après quoi elle renvoie la valeur stockée sans recalcul.

Une propriété lazy est-elle sûre dans un environnement multithread ?

L'initialisation est thread-safe — deux threads n'initialiseront pas la propriété deux fois. Cependant, les mutations ultérieures ne sont pas automatiquement synchronisées.

Une propriété lazy peut-elle être redéfinie dans une sous-classe ?

Non, les propriétés lazy ne peuvent pas être redéfinies. Une sous-classe ne peut que modifier la logique à l'intérieur de la closure, mais pas l'initialisation lazy elle-même.

Quelle est la différence entre lazy et une propriété calculée ?

Lazy est une propriété stockée qui est calculée une fois et stocke la valeur. Une propriété calculée est calculée à chaque accès et ne stocke pas de valeur.

Résumé

  • Lazy Property — mécanisme d'initialisation différée exécuté au premier accès
  • Uniquement var — lazy est incompatible avec let car une constante nécessite une initialisation immédiate
  • Unique — l'initialisation a lieu une fois, les accès suivants utilisent la valeur en cache
  • Sécurité des threads — l'initialisation est synchronisée, mais les mutations après initialisation nécessitent une synchronisation séparée
  • Utilisation — ressources lourdes, composants d'interface, services singleton, configurations
  • Limitations — ne peut pas être utilisé avec let, les propriétés calculées, la redéfinition ou les structures avec instances let
  • Optimisation — réduit le temps de démarrage et la consommation mémoire pour les propriétés rarement utilisées

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