[swift-evolution] Custom didSet methods

davesweeris at mac.com davesweeris at mac.com
Tue Jan 12 22:07:01 CST 2016

> On Jan 12, 2016, at 19:17, cocoadev at charlessoft.com wrote:
> did/willSetAtIndex could be redundant, since that information could be equally well expressed with a range having a length of 1.
Good point… Conceptually, I actually really like it. On the other hand, you could make the same argument about subscript, and the fact that the collection types implement separate functions for Index and Range<Index> makes me think there are good reasons to keep them separate (specifically I wonder about the performance implications for wrapping the common case of one Index in a Range<Index>).

> The other thing it's missing is a way to tell what kind of change it was. If something were inserted or removed such that the number of items in the collection were changed, you’d need to know about it to avoid having to redraw whatever view correspond to every single element in the collection coming after the index you've changed.
> What KVO did was to offer an NSKeyValueSetMutationKind enum containing constants for insertion and removal as well as OR and AND operations with other sets. If you don't want to do that, another possible interface could be to provide two ranges, one representing the range of the affected region before the change, and another representing it afterward. If you had an empty range for "before" and a non-empty range for "after", that would represent an insertion. The reverse would be removal, and anything else would be a replacement of some kind.
> Charles
Also, good points. I guess my idea then is:
“did/willUpdate”, “did/willInsert”, and “did/willRemove” for when you don’t care about which element was changed (and for types that aren’t indexable anyway)
“did/willUpdateAtIndex”, “did/WillInsertAtIndex”, and “did/WillRemoveAtIndex” for single elements
“did/willUpdateInRange”, “did/WillInsertInRange”, and “did/WillRemoveInRange” for multiple elements

That’s a lot of new keywords, though… Oh! What if it was *only* did/willUpdate, did/willAdd, and did/willRemove, and they were overloaded with (), (atIndex: Index), and (inRange: Range<Index>) forms? Like this:
var foo: [Int] {
	didUpdate(atIndex: Int) {
	didInsert(inRange: Range<Int>) {

Actually, could the “inRange” cases be handled simply by having the runtime call the did/will function multiple times? How much of efficiency hit would it be to have multiple function calls, compared to one function call that iterates through a range?

I like the idea of supporting this kind of “extended” did/willSet functionality, but I don’t think there should be *language features* — stuff that gets its own keyword — that necessarily have lots of runtime overhead.

- Dave

> On 2016-01-12 22:04, David Sweeris wrote:
>> What about did/willAdd for all collection types, did/willSetAtIndex
>> for collection types with indexes, and
>> did/willSetAtIndexRange for collection types that support subscripting
>> with ranges?
>> - Dave
>>> On Jan 12, 2016, at 13:26, Charles Srstka via swift-evolution <swift-evolution at swift.org> wrote:
>>> Currently, didSet already gets called when a set property is mutated. The only difference I see in this proposal is that it lets you know more precisely what changed, so that you can more efficiently update the UI to reflect the change; i.e. if each item is represented by a view object, and you insert an object, the redraw only needs to occur for the view corresponding to the newly inserted item instead of having to recreate all the views.
>>> Seems reasonable to me. KVO currently provides this facility in Objective-C.
>>> Charles
>>>> On 2016-01-12 07:33, 肇鑫 via swift-evolution wrote:
>>>> I don't know if this is a good idea. If you insert an item to an
>>>> array, what should happen? The items after the inserted item should be
>>>> considered as removed or not? They indexes are changed but the values
>>>> not.
>>>> zhaoxin
>>>> On Tue, Jan 12, 2016 at 7:24 PM, James Campbell via swift-evolution
>>>> <swift-evolution at swift.org> wrote:
>>>>> When declaring a collection, it would be nice to have a way of
>>>>> knowing when an item is set/added and removed.
>>>>> For example you could trigger a layer to be added to the layer
>>>>> hiearchy.
>>>>> var shapeLayers: [CAShapeLayer] {
>>>>> didAdd(item) {
>>>>> addSubLayer(item)
>>>>> }
>>>>> willRemove(item){
>>>>> item.removeFromSuperlayer()
>>>>> }
>>>>> }
>>>>> --
>>>>>  Wizard
>>>>> james at supmenow.com
>>>>> +44 7523 279 698 [1]
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution [2]
>>>> --
>>>> Owen Zhao
>>>> Links:
>>>> ------
>>>> [1] tel:%2B44%207523%20279%20698
>>>> [2] https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution

More information about the swift-evolution mailing list