[swift-evolution] [Draft] Obejctive-C Keypaths

David Hart david at hartbit.com
Fri Mar 4 13:13:02 CST 2016


I think KVC is going to continue being useful:
* Foundation is becoming part of the Swift portability story
* We are still at least a year and a half (Swift 4) from the kind of features which will reduce the usefulness of KVO and KVC.

It is also evident that smoothing out working with Objective-C is still greatly sought out as the #selector proposal shows.

> On 04 Mar 2016, at 18:55, Félix Cloutier <felixcca at yahoo.ca> wrote:
> 
> I think that using something like #keypath would be safer and more refactor-friendly than bare strings, but is KVC going to be an important part of Swift's future?
> 
> Félix
> 
>> Le 4 mars 2016 à 12:05:05, David Hart via swift-evolution <swift-evolution at swift.org> a écrit :
>> 
>> Hello Swift-friends,
>> 
>> After more thinking, here is a new proposal, based on my original proposal for #selector for properties but better targeted at the intended use: referencing key-paths. Please let me know what you think:
>> 
>> Referencing Objective-C key-paths
>> Proposal: SE-XXXX
>> Author(s): David Hart
>> Status: TBD
>> Review manager: TBD
>> Introduction
>> 
>> In Objective-C and Swift, key-paths used by KVC and KVO are represented as string literals (e.g., "friend.address.streetName"). This proposal seeks to improve the safety and resilience to modification of code using key-paths by introducing a compiler-checked expression.
>> 
>> Motivation
>> 
>> The use of string literals for key paths is extremely error-prone: there is no checking that the string corresponds to a valid key-path. In a similar manner to the proposal for the Objective-C selector expression SE-0022, this proposal introduces a syntax for referencing compiler-checked key-paths. When the referenced properties and methods are renamed or deleted, the programmer will be notified by a compiler error.
>> 
>> Proposed solution
>> 
>> Introduce a new expression #keypath that allows one to build a String from a key-path:
>> 
>> class Person: NSObject {
>>     dynamic var firstName: String = ""
>>     dynamic var lastName: String = ""
>>     dynamic var friends: [Person] = []
>>     dynamic var bestFriend: Person?
>> 
>>     init(firstName: String, lastName: String) {
>>         self.firstName = firstName
>>         self.lastName = lastName
>>     }
>> }
>> 
>> let chris = Person(firstName: "Chris", lastName: "Lattner")
>> let joe = Person(firstName: "Joe", lastName: "Groff")
>> let douglas = Person(firstName: "Douglas", lastName: "Gregor")
>> chris.friends = [joe, douglas]
>> chris.bestFriend = joe
>> 
>> 
>> #keypath(Person.firstName) // => "firstName"
>> chris.valueForKey(#keypath(Person.firstName)) // => Chris
>> #keypath(Person.bestFriend.lastName) // => "bestFriend.lastName"
>> chris.valueForKeyPath(#keypath(Person.bestFriend.lastName)) // => Groff
>> #keypath(Person.friends.firstName) // => "friends.firstName"
>> chris.valueForKeyPath(#keypath(Person.friends.firstName)) // => ["Joe", "Douglas"]
>> By having the #keypath expression do the work to form the Objective-C key-path string, we free the developer from having to do the manual typing and get static checking that the key-path exists and is exposed to Objective-C.
>> 
>> Impact on existing code
>> 
>> The introduction of the #keypath expression has no impact on existing code as it returns a String. It is simply a modification-safe alternative to using literal strings for referencing key-paths.
>> 
>> Alternatives considered
>> 
>> One aspect of the design which seems potentially complicated is the reference to key-paths which include an collection in the middle of the path.
>> 
>> chris.valueForKeyPath(#keypath(Person.friends.firstName))
>> The above example is potentially harder to implement because the argument of #keypath is not a valid Swift expression, compared to the other two examples. An alternative would be to remove the ability to reference those key-paths, making the proposal less useful, but easier to implement.
>> _______________________________________________
>> swift-evolution mailing list
>> swift-evolution at swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160304/aae798aa/attachment.html>


More information about the swift-evolution mailing list