programowanieiOS developer

Czym są key-paths w Swift? Jak używać WritableKeyPath i po co są potrzebne, jakie problemy rozwiązują, jakie pułapki istnieją przy pracy z KeyPath API?

Zdaj rozmowy kwalifikacyjne z asystentem AI Hintsage

Odpowiedź.

Key-path (kluczowa ścieżka) — mechanizm bezpiecznego dostępu do właściwości obiektów "po referencji". Dają pełny dostęp typu-safe do właściwości:

struct Person { var name: String var age: Int } let kp = \Person.name let john = Person(name: "John", age: 30) print(john[keyPath: kp]) // "John"

WritableKeyPath — pozwala nie tylko czytać, ale i zmieniać właściwości:

var person = Person(name: "Foo", age: 22) let namePath: WritableKeyPath<Person, String> = \Person.name person[keyPath: namePath] = "Bar"

Zastosowanie:

  • Stosowane do ogólnej pracy z modelami (na przykład przy sortowaniu, filtrowaniu, powiązaniu danych z UI).
  • Wygodne do budowy przyjaznej dla użytkownika refleksji bez utraty bezpieczeństwa typów.

Szczegóły:

  • KeyPath tylko dla właściwości, do których możliwy jest dostęp kompilatora.
  • KeyPath nie może przechowywać metod, tylko właściwości.
  • Dla WritableKeyPath obiekt (struktura) musi być var.

Pytanie z haczykiem.

Pytanie: "Czy można zmieniać właściwości klasy przez zwykły KeyPath (czy potrzebny jest WritableKeyPath)? Czym różnią się KeyPath i ReferenceWritableKeyPath?"

Odpowiedź: Aby zmienić wartość właściwości za pomocą key path, potrzebny jest WritableKeyPath. Dla klas istnieje również ReferenceWritableKeyPath, który umożliwia zmianę właściwości za pomocą key-path dla typów referencyjnych.

class User { var score = 0 } let user = User() let path: ReferenceWritableKeyPath<User, Int> = \User.score user[keyPath: path] = 42 // OK

Przykłady rzeczywistych błędów z powodu niewiedzy na temat szczegółów.


Historia

W dużym projekcie UI opartym na tabelach pomylono zwykłe KeyPath i WritableKeyPath — próbowano zmienić właściwość modelu za pomocą KeyPath, co skutkowało wyjątkiem runtime.


Historia

Podczas generowania genericznych formularzy użyto KeyPath do powiązania wartości, ale próbowano reflektować metody jako keypaths, co prowadziło do niemożności kompilacji i skomplikowania kodu.


Historia

Programista zapominał dodawać ReferenceWritableKeyPath dla klas, co utrudniało bidirectional binding między UI a modelem danych: wartości były aktualizowane w UI, ale model pozostawał niezmieniony.