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 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.
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.
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.
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.
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.
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é.
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
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.
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.
Les propriétés lazy sont utilisées dans les projets Swift pour optimiser les performances et améliorer l'architecture du code.
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.
class ProfileViewController {
lazy var avatarImageView: UIImageView = {
let imageView = UIImageView()
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
return imageView
}()
}
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.
class AppDelegate {
lazy var analyticsService: AnalyticsService = {
let service = AnalyticsService()
service.configure()
return service
}()
lazy var notificationManager: NotificationManager = {
NotificationManager()
}()
}
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.
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
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.
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.
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.
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.
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é
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.
Lisez aussi