Comment réussir un entretien Swift : les questions avancées incontournables

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

Comment réussir un entretien Swift : les questions avancées incontournables



Un entretien pour un poste de développeur iOS ne se limite pas à vérifier vos connaissances d'UIKit et SwiftUI. Au niveau avancé, les recruteurs et les responsables techniques veulent s'assurer que vous comprenez le fonctionnement de la mémoire, la différence entre class et struct dans le contexte du comptage de références, comment bien structurer une architecture avec des protocoles et comment gérer l'asynchronisme. Dans cet article, nous analysons les sujets clés souvent abordés lors des entretiens Swift de niveau Middle et Senior.



1. Gestion de la mémoire et ARC (Automatic Reference Counting)



L'ARC est l'un des sujets les plus fréquents en entretien. Vous devez non seulement connaître la théorie, mais aussi savoir expliquer comment éviter les fuites mémoire.



1.1. Comment fonctionne l'ARC et quels sont les cycles de références fortes ?



L'ARC compte automatiquement le nombre de références fortes vers un objet de classe. Dès que le compteur atteint zéro, l'objet est supprimé de la mémoire. Le problème survient lorsque deux objets se référencent mutuellement de manière forte, créant un cycle (retain cycle).



class Parent {    var child: Child?}

class Child { var parent: Parent? // référence forte retour}

var parent: Parent? = Parent()var child: Child? = Child()parent?.child = childchild?.parent = parent// Les deux objets ne seront jamais libérés


1.2. Comment briser le cycle ?



Utilisez weak ou unowned. weak est une référence optionnelle qui devient automatiquement nil lors de la suppression de l'objet. unowned est non optionnelle, mais suppose que l'objet vivra au moins aussi longtemps que l'objet qui le référence.



class Child {    weak var parent: Parent?  // référence faible}


1.3. Comment l'ARC fonctionne-t-il avec les closures ?



Les closures capturent les variables externes. Si une closure est stockée comme propriété d'une classe et qu'elle utilise self à l'intérieur, un cycle se crée. La solution est d'utiliser [weak self] ou [unowned self].



class NetworkManager {    var completionHandler: (() -> Void)?        func fetchData() {        completionHandler = { [weak self] in            guard let self = self else { return }            self.processData()        }    }        func processData() { }}


2. Closures : escaping vs non-escaping



Comprendre la différence entre les closures escaping et non-escaping est un point obligatoire pour tout poste avancé.



2.1. Qu'est-ce qu'une closure escaping ?



Une closure est dite escaping si elle peut être appelée après le retour de la fonction. Par défaut, toutes les closures sont non-escaping — le compilateur sait qu'elles seront exécutées à l'intérieur du corps de la fonction. Pour les opérations asynchrones (par exemple, les requêtes réseau), il faut explicitement indiquer @escaping.



func performAsyncTask(completion: @escaping (String) -> Void) {    DispatchQueue.global().async {        // Simulation d'une tâche longue        sleep(2)        completion("Prêt")    }}


2.2. Pourquoi les closures non-escaping sont-elles plus rapides ?



Le compilateur optimise les closures non-escaping — il peut ne pas les copier dans le tas (heap), mais les stocker sur la pile. Il peut également éviter le comptage de références, car la durée de vie de la closure est limitée à l'appel de la fonction.



3. Génériques et protocoles avec types associés (PAT)



Les génériques sont la base de Swift. Lors d'un entretien, on peut vous demander d'écrire une structure générique ou d'expliquer comment fonctionnent les protocoles avec des types associés.



3.1. Écrivez une file d'attente (Queue) générique



struct Queue<T> {    private var elements: [T] = []        mutating func enqueue(_ value: T) {        elements.append(value)    }        mutating func dequeue() -> T? {        guard !elements.isEmpty else { return nil }                

Blogs

Book Recommendations