ProgrammationDéveloppeur iOS senior

Comment fonctionnent les propriétés static et class en Swift, quels pièges peuvent survenir lors de leur utilisation et comment réaliser des statiques thread-safe ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Les propriétés static et class sont des propriétés qui appartiennent au type plutôt qu'à l'instance. Historiquement, elles sont apparues pour résoudre le problème du stockage d'informations partagées entre toutes les instances (par exemple, des compteurs, des configurations, des fabriques). En Swift, static peut être utilisé dans tous les types (class, struct, enum), tandis que class ne peut être utilisé que dans des classes et uniquement pour des propriétés calculées, permettant la redéfinition dans les sous-classes.

Problème : une mauvaise utilisation des propriétés statiques peut entraîner des conditions de course et des erreurs d'accès depuis différents threads. Il est également facile de confondre static et class et de choisir incorrectement le mécanisme pour le remplacement dans les sous-classes.

Solution :

  • Utiliser static pour des propriétés immuables ou clairement thread-safe.
  • Pour l'héritage et le remplacement, définir class property.
  • Pour la sécurité des threads, stocker les données dans un stockage statique privé et y accéder uniquement via une logique synchronisée (par exemple, via DispatchQueue).

Exemple de code :

class Counter { static var count = 0 static let queue = DispatchQueue(label: "counter.queue") static func increment() { queue.sync { count += 1 } } class var typeDescription: String { return "Compteur Générique" } } class NamedCounter: Counter { override class var typeDescription: String { return "Compteur Nommé" } }

Caractéristiques clés :

  • static ne peut pas être redéfini, class var peut l'être.
  • static fonctionne pour tous les types, class uniquement pour les classes.
  • Les propriétés statiques sont une seule copie par type, accessibles de n'importe où dans le code.

Questions pièges.

Question 1 : Peut-on déclarer une propriété static let comme propriété calculée (computed) avec get ?

Oui, une propriété static peut être à la fois stockée et calculée. Pour les propriétés let, il s'agit généralement d'une constante, mais une static var peut tout à fait être calculée :

struct Math { static var pi: Double { return 3.1415926 } }

Question 2 : Les static var sont-elles thread-safe par défaut ?

Non, si static var est modifié à partir de différents threads, des conditions de course peuvent survenir. Les opérations de lecture/écriture doivent être synchronisées manuellement.

Question 3 : Peut-on utiliser class var pour des propriétés stockées ?

Non, class var doit toujours être une propriété calculée (property with get/optional set), les propriétés stockées ne sont autorisées que pour static.

Erreurs types et anti-patterns

  • Laisser static var sans synchronisation dans un environnement multi-thread.
  • Essayer de déclarer class var comme stockée.
  • Confondre static et class en choisissant le mauvais mécanisme pour l'héritage.

Exemple de la vie réelle

Cas négatif

Dans une application, le compteur de connexions utilisateur était stocké dans une static var et incrémenté depuis différents threads sans synchronisation.

Avantages :

  • Facile à mettre en œuvre.

Inconvénients :

  • Finalement, le compteur donnait parfois des valeurs incorrectes, compliquant le débogage et le suivi des bogues.

Cas positif

Pour un objet de configuration global, nous avons utilisé static let et l'accès à celui-ci était uniquement en lecture ou avec DispatchQueue pour écrire.

Avantages :

  • Absence de conditions de course et comportement prévisible.
  • Soutien de la sécurité des threads.

Inconvénients :

  • Un peu plus de code en raison de l'encapsulation dans la file d'attente.