ProgrammationDéveloppeur iOS

Comment fonctionnent les structures (struct) en Swift, quelle est la différence avec les objets de classe (class) en termes de stockage et de comportement, et pourquoi les structures sont-elles souvent utilisées pour modéliser des données ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse.

Historique de la question

Dès le début, Swift a mis l'accent sur les value types — les structures (struct) comme principal outil de modélisation des données. Contrairement à l'Objective-C, où tout était des objets (classes), Swift encourage l'utilisation des structures pour des modèles simples, des données et des petits objets métier.

Problème

De nombreux développeurs, en particulier ceux ayant de l'expérience avec d'autres langages orientés objet, utilisent par erreur des classes pour tout. Cela conduit à des problèmes de mémoire (cycles de référence), à des modifications inattendues lors de la transmission d'objets et à des difficultés avec la sécurité des threads, car les classes sont des types de référence.

Solution

Les structures en Swift sont des value types, elles sont copiées lors de l'affectation et de la transmission dans des fonctions, contrairement aux classes (types de référence), qui transmettent une référence. C'est justement ce qui rend les structures préférables pour des modèles sans logiques complexes de cycle de vie et d'héritage.

Exemple de code :

struct Point { var x: Int var y: Int } var p1 = Point(x: 10, y: 20) var p2 = p1 p2.x = 30 // p1.x reste égal à 10

Caractéristiques clés :

  • La copie d'une structure entraîne toujours une copie des valeurs (sémantique de valeur)
  • Moins de possibilités de fuites de mémoire
  • Ne supportent pas l'héritage, uniquement les protocoles

Questions pièges.

Une structure peut-elle avoir un sous-classe ?

Non, les structures en Swift ne supportent pas l'héritage. Toute extension du comportement est possible uniquement via des protocoles et des extensions.

Cela signifie-t-il qu'une structure est toujours copiée lors de sa transmission dans une fonction ?

En pratique, Swift utilise des optimisations Copy-On-Write. Si nous ne modifions pas la structure, elle n'est pas copiée, une copie n'est créée qu'en cas de modification. Cela s'applique aux collections standard et aux structures complexes.

var arr1 = [1, 2, 3] var arr2 = arr1 arr2.append(4) // C'est ici que la copie se produit

Dans quels cas ne pas utiliser une structure ?

  • Si une identité est requise (objet, comparaison par référence)
  • Si un héritier est nécessaire
  • S'il doit y avoir une seule instance (singleton)

Erreurs typiques et anti-patrons

  • Utiliser des classes pour des modèles simples et des structures de données
  • Stocker des types de référence à l'intérieur d'une structure et essayer de les copier
  • Attendre de transmettre une structure "par référence" et tenter de modifier un objet externe via la structure

Exemple de la vie réelle

Cas négatif

Utiliser des classes pour stocker des données homogènes (par exemple, pour des points sur une carte), entraînant une perte de performance due à des accès fréquents à la mémoire, une gestion complexe de la mémoire et des bugs d''inversion de référence.

Avantages :

  • Possibilité de stocker dans un tableau comme AnyObject

Inconvénients :

  • Moins de performance
  • Difficultés avec la sécurité des threads
  • Problèmes de gestion de mémoire

Cas positif

Utilisation de structures pour des modèles de données qui se copient en toute sécurité, ne provoquent pas de fuites et n'ont pas de complexité superflue.

Avantages :

  • Simplicité, sécurité de la copie
  • Absence de cycles de référence
  • Facile à tester

Inconvénients :

  • Impossible de mettre en œuvre des patrons nécessitant de l'héritage
  • Si un type de référence est à l'intérieur d'une structure — surprises possibles lors de la copie et des modifications