Code Review in Swift: Was überprüfen und wie man Feedback in der Praxis gibt
\n\nCode Review ist nicht nur eine Formalität, sondern ein mächtiges Werkzeug zur Verbesserung der Codequalität, zur Verbreitung von Wissen im Team und zur Vermeidung von Fehlern. Wenn man das Review jedoch formal oder im Gegenteil zu aggressiv angeht, kann es mehr schaden als nützen. In diesem Artikel schauen wir uns an, worauf man bei der Überprüfung von Swift-Code für iOS und macOS konkret achten sollte und wie man Feedback formuliert, das nützlich ist und Kollegen nicht verletzt.
\n\n1. Architektur und Design: An die Wurzel gehen
\n\nBevor Sie sich in die Implementierungsdetails stürzen, bewerten Sie die Gesamtarchitektur der Lösung. Guter Code ist nicht nur Syntax, sondern auch Struktur.
\n\n- \n
- Single Responsibility Principle (SRP): Versucht die Klasse/Funktion zu viel zu tun? Mischt beispielsweise der ViewController Geschäftslogik und Netzwerkanfragen? \n
- MVVM / MVC / VIPER: Entspricht der Code dem gewählten Pattern? Wenn das Projekt MVVM verwendet, sollte die ViewModel kein
UIKitimportieren. \n - Abhängigkeitsverwaltung: Wird Dependency Injection (DI) verwendet oder werden Objekte intern erstellt? Feste Abhängigkeiten erschweren das Testen. \n
- Speicherverwaltung: Gibt es Speicherlecks? Überprüfen Sie
@escaping-Closures, starke Referenzen aufselfund mögliche zyklische Referenzen. \n
// Schlecht: starke Referenz auf self in einer Closure\nclass NetworkManager {\n var onComplete: (() -> Void)?\n\n func fetchData() {\n URLSession.shared.dataTask(with: URL(string: "https://api.example.com")!) { data, _, _ in\n self.onComplete?() // Speicherleck! Die Closure hält eine starke Referenz auf self\n }.resume()\n }\n}\n\n// Gut: Verwendung von [weak self]\nclass NetworkManager {\n var onComplete: (() -> Void)?\n\n func fetchData() {\n URLSession.shared.dataTask(with: URL(string: "https://api.example.com")!) { [weak self] data, _, _ in\n DispatchQueue.main.async {\n self?.onComplete?()\n }\n }.resume()\n }\n}\n\n2. Typsicherheit und Optionalität: Die Stärken von Swift nutzen
\n\nSwift ist eine streng typisierte Sprache, und das sollte sich im Code Review widerspiegeln. Vermeiden Sie "ObjC-Code im Swift-Gewand".
\n\n- \n
- Force Unwrapping: Gibt es
!an Stellen, an denen es vermieden werden kann? Verwenden Sieguard letoderif let. \n - Enumerationen (Enums): Werden sie anstelle von String-Konstanten verwendet? Zum Beispiel für Antwortstatus oder Fehlertypen. \n
- Result-Typ: Wird der Fehler über
Result<Success, Failure>behandelt, anstatt einen optionalen Wert und einen separaten Fehler zurückzugeben? \n - Generics: Wie angemessen ist die Verwendung von Generika? Manchmal erschweren sie den Code ohne Notwendigkeit. \n
// Schlecht: Force Unwrap und String-Konstanten\nfunc getUser(id: String!) -> User? {\n if id == "admin" {\n return User(name: "Admin")\n }\n return nil\n}\n\n// Gut: Enum und sicheres Entpacken\nenum UserType: String {\n case admin\n case regular\n}\n\nfunc getUser(id: String?) -> User? {\n guard let userId = id, let userType = UserType(rawValue: userId) else {\n return nil\n }\n // ... Logik\n return User(name: userType.rawValue)\n}\n\n3. Leistung und Arbeit mit der UI: Akku und FPS schonen
\n\nFür iOS/macOS-Anwendungen sind flüssige Animationen und Energieeffizienz entscheidend. Achten Sie auf:
\n\n- \n
- Main Thread: Alle UI-Updates müssen im Hauptthread erfolgen. Überprüfen Sie, ob es Aufrufe von
UIViewoderNSViewaus Hintergrundwarteschlangen gibt. \n - Schwere Berechnungen: Werden komplexe Operationen nicht im Hauptthread ausgeführt? \n