ProgrammationDéveloppeur iOS

Quelles sont les principales différences entre les propriétés lazy en Swift ? Quand faut-il utiliser lazy, quelles sont les particularités et les pièges lors de leur initialisation, et comment éviter les problèmes typiques ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les propriétés lazy en Swift ne sont calculées qu'à la première utilisation. Cela est souvent utilisé pour des objets gourmands en ressources (par exemple, des calculs lourds, des chargements réseau) qui ne sont pas nécessaires immédiatement. Elles sont déclarées avec le mot-clé lazy :

class DataFetcher { lazy var data: Data = self.loadData() func loadData() -> Data { /* … */ } }

Particularités et nuances :

  • Les propriétés lazy ne sont autorisées que pour les variables (var), pas pour les constantes (let).
  • À l'intérieur des structures, les propriétés lazy ne fonctionnent pas si la structure elle-même est immutable.
  • Si définies à travers un autre thread — elles ne sont pas thread-safe. Il est préférable d'éviter l'accès simultané aux propriétés lazy depuis différents threads.
  • Lors de la copie d'un objet de classe, la valeur lazy est mise en cache pour chaque instance séparément.

Question piégée.

Question : "Une valeur pour la propriété lazy est-elle créée lors de l'initialisation d'une instance de classe ?"

Réponse : Non, la valeur est calculée uniquement lors du premier accès à la propriété, et non lors de l'initialisation.

class Expensive { init() { print("init") } } class Example { lazy var heavy = Expensive() } let foo = Example() // rien ne s'affiche _ = foo.heavy // maintenant "init"

Exemples d'erreurs réelles dues à une méconnaissance des subtilités du sujet.


Histoire

Dans un projet multi-plateforme, un tableau lazy (lazy var) était utilisé pour stocker un cache d'images. Lors de l'accès simultané depuis plusieurs threads, des courses sont survenues, nous avons enveloppé lazy var avec des mutex — mais avons oublié la nature lazy, ce qui a conduit à un plantage de l'application.


Histoire

Un jeune développeur tentait de déclarer un lazy let pour mettre en cache un calcul lourd. Le code ne compilait pas, car lazy n'est autorisé que pour var : il a dû revoir l'architecture.


Histoire

Un développeur a déclaré une propriété lazy avec une capture de self à l'intérieur d'un closure lors de l'initialisation. Cela a conduit à une référence circulaire — l'objet n'a pas été désinitialisé même après avoir quitté tous les écrans.