[swift-users] strange property observer behavior

Zhao Xin owenzx at gmail.com
Sun Sep 4 16:25:38 CDT 2016


It seems like a bug. You should file it.

Zhaoxin

On Sun, Sep 4, 2016 at 11:11 PM, <adelzhang at qq.com> wrote:

> Thanks for reply.
>
> How does Swift choose *rules* as you said?
>
> Swfit encourage to override the property observer. But when we change the
> own property in Child class's `didSet` observer, that would cause infinite
> loop:
>
>     class Base {
>         var a: Int = 0
>     }
>
>     class Child : Base {
>         override var a: Int {
>             didSet {
>                  a = a + 1
>             }
>         }
>      }
>
>      let child = Child()
>      child.a = 3
>
> Any differcen with situation 1?
>
>
> 在 Sun, 04 Sep 2016 20:12:42 +0800,Zhao Xin <owenzx at gmail.com> 写道:
>
> 1) when `didSet` observer will call?
>
>
> ​For me, it is more like Swift developer tries to override some beginner's
>> flaw.
>
>
> Above is incorrect. You can change property's value in `didSet`, that
> won't cause didSet called again as it is intended to give you the
> opportunity to do that.
>
> ​2) infinite loop
>
>
> This can't apply the above rule as they set each other, causing the
> infinite loops.
>
> Zhaoxin
>
>
> On Sun, Sep 4, 2016 at 7:41 PM, Zhao Xin <owenzx at gmail.com> wrote:
>
>> 1) when `didSet` observer will call?
>>
>>
>> ​For me, it is more like Swift developer tries to override some
>> beginner's flaw.
>>
>> ​2) infinite loop
>>
>>
>> ​If you intended to do things bad, things ​went bad.
>>
>> 3) override property observer
>>
>>
>> ​You mentioned "TSPL(The Swift Programming Language) ​", and it says in
>> it:
>>
>> “NOTE
>>
>> The willSet and didSet observers of superclass properties are called when
>> a property is set in a subclass initializer, after the superclass
>> initializer has been called. They are not called while a class is setting
>> its own properties, before the superclass initializer has been called.
>>
>> For more information about initializer delegation, see Initializer
>> Delegation for Value Types and Initializer Delegation for Class Types.”
>>
>> From: Apple Inc. “The Swift Programming Language (Swift 3 Beta)”。 iBooks.
>> https://itun.es/us/k5SW7.l
>>
>> You didn't provide a `init()`, but since you properties were already set.
>> There was a hidden `init()` when you called `Child()`.
>>
>> Last,
>>
>>  let base = child as Base
>>  base.a  = 4 // still output "base didset" and "child didset"
>>
>> In Swift, as or as! won't change the instance's dynamic type. So it does
>> nothing. `type(of:base)` is still `Child`.
>>
>> Zhaoxin
>>
>>
>>
>> On Sun, Sep 4, 2016 at 6:25 PM, adelzhang via swift-users <
>> swift-users at swift.org> wrote:
>>
>>> Hi all
>>>
>>> It sounds convenient to monitor change in property's value using
>>> property observer.
>>> But TSPL(The Swift Programming Language) talk little about property
>>> observer. There
>>> are some questions abouts property observer.
>>>
>>> 1) when `didSet` observer will call?
>>>
>>> I assume it's fine that changing property's value in `didSet` observer.
>>>
>>>     class Foo {
>>>         var a: Int = 0 {
>>>             didSet {
>>>                 print("didset")
>>>                 a = a + 1
>>>             }
>>>         }
>>>     }
>>>
>>>     let foo = Foo()
>>>     foo.a = 4  // only output "didset" once
>>>
>>> Why it don't cause infinite loop?
>>>
>>> 2) infinite loop
>>>
>>>     // this code snippet cause inifinite loop
>>>     class Foo {
>>>         var a: Int = 0 {
>>>             didSet {
>>>                 b = a + 1
>>>             }
>>>         }
>>>
>>>         var b: Int = 1 {
>>>             didSet {
>>>                 a = b - 1
>>>             }
>>>         }
>>>     }
>>>
>>>     let foo = Foo()
>>>     foo.a = 2
>>>
>>> 3) override property observer
>>>
>>>     class Base {
>>>         var a: Int = 0 {
>>>             didSet {
>>>                 print("base didset")
>>>             }
>>>         }
>>>     }
>>>
>>>     class Child : Base {
>>>         override var a : Int {
>>>             didSet {
>>>                 print("child didset")
>>>             }
>>>         }
>>>     }
>>>
>>>     let child = Child()
>>>     child.a = 2 // output "base didset" and "child didset"
>>>     let base = child as Base
>>>     base.a  = 4 // still output "base didset" and "child didset"
>>>
>>> Why overriding property observer still call parent's `didSet` observer?
>>>
>>> --
>>> Adel
>>>
>>>
>>> _______________________________________________
>>> swift-users mailing list
>>> swift-users at swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>
>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160905/284b660b/attachment.html>


More information about the swift-users mailing list