Top erreurs des développeurs Swift débutants : niveau avancé

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Top erreurs des développeurs Swift débutants : niveau avancé



Lorsque vous passez de l'écriture d'écrans simples en SwiftUI à la création d'applications multithread complexes avec une architecture personnalisée, le nombre d'embûches augmente considérablement. De nombreux développeurs, après avoir maîtrisé la syntaxe de base de Swift, se croient prêts pour la production, mais commettent des erreurs critiques qui entraînent des fuites mémoire, un fonctionnement instable et des bugs difficiles à détecter. Dans cet article, nous analyserons quatre catégories d'erreurs les plus fréquentes chez les développeurs de niveau intermédiaire.



1. Fuites mémoire dans les closures : pas seulement [weak self]



L'erreur la plus courante est l'utilisation de [weak self] sans comprendre quand cela est réellement nécessaire. De nombreux développeurs mettent weak self partout où il y a une closure, ce qui entraîne la destruction prématurée des objets. Ou, à l'inverse, ils oublient les cycles de référence forts dans des endroits non évidents.



Erreur typique : création d'une référence forte sur un objet à l'intérieur d'une closure que cet objet stocke.



class NetworkManager {    var onCompletion: (() -> Void)?        func fetchData() {        // ERREUR : la closure capture self fortement        onCompletion = {            self.updateUI()        }    }        func updateUI() {        print("UI mis à jour")    }}


Solution correcte : utiliser [weak self] ou [unowned self] en fonction de la durée de vie des objets.



class NetworkManager {    var onCompletion: (() -> Void)?        func fetchData() {        onCompletion = { [weak self] in            guard let self = self else { return }            self.updateUI()        }    }        func updateUI() {        print("UI mis à jour")    }}


Nuance avancée : soyez prudent avec [unowned self]. Si l'objet est libéré et que la closure est appelée, l'application plantera. Utilisez unowned uniquement lorsque vous êtes sûr à 100% que l'objet survivra à la closure.



2. Mauvaise gestion de async/await et des acteurs



Avec l'arrivée de Structured Concurrency dans Swift 5.5, de nombreux développeurs ont commencé à utiliser activement async/await, mais oublient MainActor et Sendable. Cela entraîne des race conditions et des mises à jour de l'UI depuis un thread d'arrière-plan.



Erreur typique : appel d'une fonction asynchrone qui doit s'exécuter sur le thread principal sans spécifier explicitement @MainActor.



class ViewModel: ObservableObject {    @Published var data: [String] = []        // ERREUR : la fonction n'est pas marquée @MainActor    func loadData() async {        let result = await fetchFromNetwork()        // Cela peut s'exécuter sur un thread d'arrière-plan !        self.data = result    }        func fetchFromNetwork() async -> [String] {        try? await Task.sleep(nanoseconds: 1_000_000_000)        return ["Item1", "Item2"]    }}


Solution correcte : utiliser @MainActor pour les fonctions qui mettent à jour l'UI.



class ViewModel: ObservableObject {    @Published var data: [String] = []        @MainActor // Maintenant exécuté garantie sur le thread principal    func loadData() async {        let result = await fetchFromNetwork()        self.data = result    }        func fetchFromNetwork() async -> [String] {        try? await Task.sleep(nanoseconds: 1_000_000_000)        return ["Item1", "Item2"]    }}


Nuance avancée : n'oubliez pas nonisolated et actor. Si vous utilisez des acteurs, toutes les méthodes publiques sont asynchrones par défaut. Cela peut entraîner des retards inattendus si vous ne planifiez pas l'isolation.



3. Race Conditions dans

Blogs

Book Recommendations