Override Lazy Stored Property

I'm interested to know if overriding a lazy stored property in a sub-class
is recommended or not. For example:

class CustomSegue: NSStoryboardSegue {
    lazy var animator: CustomAnimator()

    override func prepare() {
         ....
    }
}

class CustomSlideRightSegue: CustomSegue {
     override lazy var animator: CustomAnimator(.slideRight)
}

This works fine and the compiler does not complain. However:

1. Why is overriding lazy stored properties supported, while overriding a
non-lazy stored property is not.

2. Is this behaviour intended and/or recommended.

3. I realise you can achieve the same result by overriding init in the
sub-class and assigning to a non-lazy property, however often this reduces
clarity and introduces un-necessary boiler-plate code (especially if init
takes a number of args).

Thanks!

John

This isn’t supposed to be supported, and you get a warning for it in Swift 4.1 (see SR-6165 <https://bugs.swift.org/browse/SR-6165>). I mentioned this in the fix:

Arguably we could allow overriding with a stored property. The original concerns were that you could accidentally end up with extra storage you didn't need, and that observing accessors would behave differently based on whether or not the property was overriding. But there's at least no ambiguity for 'lazy', which can't have observing accessors today.

If you want to get this behavior, you can make a second private lazy property, and override the public property with a getter that just forwards to the lazy property.

Sorry for the confusion!
Jordan

···

On Jan 11, 2018, at 02:56, John Buckley via swift-users <swift-users@swift.org> wrote:

I'm interested to know if overriding a lazy stored property in a sub-class is recommended or not. For example:

class CustomSegue: NSStoryboardSegue {
    lazy var animator: CustomAnimator()

    override func prepare() {
         ....
    }
}

class CustomSlideRightSegue: CustomSegue {
     override lazy var animator: CustomAnimator(.slideRight)
}

This works fine and the compiler does not complain. However:

1. Why is overriding lazy stored properties supported, while overriding a non-lazy stored property is not.

2. Is this behaviour intended and/or recommended.

3. I realise you can achieve the same result by overriding init in the sub-class and assigning to a non-lazy property, however often this reduces clarity and introduces un-necessary boiler-plate code (especially if init takes a number of args).

Thanks!

John
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Hi Jordan,

Thanks for the explanation - much appreciated.

It's a shame stored properties can't be overridden, but I can see how there
are issues around observers etc.

For now I've switched to a private backing property and a factory method,
similar to what you suggested.

John

···

On Thu, 11 Jan 2018 at 18:51 Jordan Rose <jordan_rose@apple.com> wrote:

This isn’t supposed to be supported, and you get a warning for it in Swift
4.1 (see SR-6165 <https://bugs.swift.org/browse/SR-6165>). I mentioned
this in the fix:

Arguably we could allow overriding with a stored property. The original
concerns were that you could accidentally end up with extra storage you
didn't need, and that observing accessors would behave differently based on
whether or not the property was overriding. But there's at least no
ambiguity for 'lazy', which can't have observing accessors today.

If you want to get this behavior, you can make a *second* private lazy
property, and override the public property with a getter that just forwards
to the lazy property.

Sorry for the confusion!
Jordan

On Jan 11, 2018, at 02:56, John Buckley via swift-users < > swift-users@swift.org> wrote:

I'm interested to know if overriding a lazy stored property in a sub-class
is recommended or not. For example:

class CustomSegue: NSStoryboardSegue {
    lazy var animator: CustomAnimator()

    override func prepare() {
         ....
    }
}

class CustomSlideRightSegue: CustomSegue {
     override lazy var animator: CustomAnimator(.slideRight)
}

This works fine and the compiler does not complain. However:

1. Why is overriding lazy stored properties supported, while overriding a
non-lazy stored property is not.

2. Is this behaviour intended and/or recommended.

3. I realise you can achieve the same result by overriding init in the
sub-class and assigning to a non-lazy property, however often this reduces
clarity and introduces un-necessary boiler-plate code (especially if init
takes a number of args).

Thanks!

John

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Ah, to be clear, it's not that stored properties can't be overridden, it's that the override can't introduce new storage. (I think you got that, but didn't want a passerby to be confused.)

Jordan

···

On Jan 12, 2018, at 09:09, John Buckley <john@olivetoast.com> wrote:

Hi Jordan,

Thanks for the explanation - much appreciated.

It's a shame stored properties can't be overridden, but I can see how there are issues around observers etc.

For now I've switched to a private backing property and a factory method, similar to what you suggested.

John

On Thu, 11 Jan 2018 at 18:51 Jordan Rose <jordan_rose@apple.com <mailto:jordan_rose@apple.com>> wrote:
This isn’t supposed to be supported, and you get a warning for it in Swift 4.1 (see SR-6165 <https://bugs.swift.org/browse/SR-6165>). I mentioned this in the fix:

Arguably we could allow overriding with a stored property. The original concerns were that you could accidentally end up with extra storage you didn't need, and that observing accessors would behave differently based on whether or not the property was overriding. But there's at least no ambiguity for 'lazy', which can't have observing accessors today.

If you want to get this behavior, you can make a second private lazy property, and override the public property with a getter that just forwards to the lazy property.

Sorry for the confusion!
Jordan

On Jan 11, 2018, at 02:56, John Buckley via swift-users <swift-users@swift.org <mailto:swift-users@swift.org>> wrote:

I'm interested to know if overriding a lazy stored property in a sub-class is recommended or not. For example:

class CustomSegue: NSStoryboardSegue {
    lazy var animator: CustomAnimator()

    override func prepare() {
         ....
    }
}

class CustomSlideRightSegue: CustomSegue {
     override lazy var animator: CustomAnimator(.slideRight)
}

This works fine and the compiler does not complain. However:

1. Why is overriding lazy stored properties supported, while overriding a non-lazy stored property is not.

2. Is this behaviour intended and/or recommended.

3. I realise you can achieve the same result by overriding init in the sub-class and assigning to a non-lazy property, however often this reduces clarity and introduces un-necessary boiler-plate code (especially if init takes a number of args).

Thanks!

John

_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users