Key-path (sleutelpad) is een mechanisme voor veilige toegang tot objecteigenschappen "via referentie". Ze bieden volledige type-veilige toegang om toegang te krijgen tot eigenschappen:
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 — stelt je in staat om niet alleen te lezen, maar ook om eigenschappen te wijzigen:
var person = Person(name: "Foo", age: 22) let namePath: WritableKeyPath<Person, String> = \Person.name person[keyPath: namePath] = "Bar"
Gebruik:
Fijnere dingen:
WritableKeyPath moet het object (structuur) var zijn.Vraag: "Kun je eigenschappen van een klasse wijzigen via een normale KeyPath (of is WritableKeyPath vereist)? Wat zijn de verschillen tussen KeyPath en ReferenceWritableKeyPath?"
Antwoord: Voor het wijzigen van de waarde van een eigenschap via een key path is een WritableKeyPath vereist. Voor klassen bestaat er ook een ReferenceWritableKeyPath, waarmee je eigenschappen via key-path voor referentietypes kunt wijzigen.
class User { var score = 0 } let user = User() let path: ReferenceWritableKeyPath<User, Int> = \User.score user[keyPath: path] = 42 // OK
Verhaal
In een groot project met een table-driven UI werden normale KeyPath en WritableKeyPath door elkaar gehaald — geprobeerd om een eigenschap van het model te wijzigen via KeyPath, wat resulteerde in een runtime-exceptie.
Verhaal
Bij het genereren van generieke formulieren werden KeyPath gebruikt voor waardeverbindingen, maar geprobeerd om methoden als keypaths te reflecteren, wat leidde tot compilatiefouten en overcomplicatie van de code.
Verhaal
De ontwikkelaar vergat ReferenceWritableKeyPath voor klassen toe te voegen, wat bidirectionele binding tussen de UI en het datamodel in de weg stond: waarden werden in de UI bijgewerkt, maar het model bleef hetzelfde.