[swift-users] didSet and time when propagation of mutation happens

Diego Sánchez diego.sanchezr at gmail.com
Thu Jul 14 17:17:01 CDT 2016


I don't know... when didSet is called the struct is already mutated so I
would expect all the references to be updated as well.

Regarding the capture in the closure it should always capture a reference
to "myClass", and call the accessors in the moment the closure is executed.
Adding

myClass.myString.value = "3"

will print "2".

because myClass.myString still holds the previous struct.

I will solve this problem by making Observable a reference type, but I was
wondering if someone could share more details about this behaviour.
Cheers,
Diego.




2016-07-14 5:19 GMT+02:00 Zhao Xin <owenzx at gmail.com>:

> I think the order is right.
>
> value.set >> value.didSet >> string.set >> string.didSet
>
> you expected value.set >> string.set >>  value.didSet >> string.didSet is
> not correct.
>
> The value "1" is not you expected. However, that is something that I think
> is tricky. For closure
>
>>  {
>>     print(myClass.myString.value)
>> }
>
> it captured the value. However, unless Objective-C, Swift will decide if
> it is a static capture or an inout capture. So it should be consider right
> to  be "1" or "2"? I am not sure about that.
>
> Zhaoxin
>
> On Thu, Jul 14, 2016 at 8:36 AM, Diego Sánchez <swift-users at swift.org>
> wrote:
>
>> Hi all,
>>
>> The following snippet summarises an issue I was investigating:
>>
>> struct Observable<T> {
>>     var value: T {
>>         didSet {
>>             print("Observable.didSet")
>>             callback?()
>>         }
>>     }
>>     var callback: (() -> Void)?
>> }
>>
>> class MyClass {
>>     var myString: Observable<String> {
>>         get {
>>             return _myString
>>         }
>>         set {
>>             print("MyClass.Setter")
>>             self._myString = newValue
>>         }
>>     }
>>
>>     private var _myString: Observable<String>
>>     init (string: Observable<String>) {
>>         self._myString = string
>>         print("MyClass.init.end")
>>     }
>> }
>>
>> let myClass = MyClass(string: Observable<String>(value: "1", callback:
>> nil))
>> myClass.myString.callback = {
>>     print(myClass.myString.value)
>> }
>> myClass.myString.value = "2"
>>
>> *Output:*
>> MyClass.init.end
>> MyClass.Setter
>> Observable.didSet
>> *1*
>> MyClass.Setter
>>
>> Obviously I wasn't expecting to get "1", but "2" in the callback's print,
>> and this happens because MyClass.setter is called after Observable.didSet
>> completes.
>>
>> Is it feasible that all the *set*s are called first, and then all the
>> *didSet*s?
>>
>> Cheers,
>> Diego
>>
>> _______________________________________________
>> 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/20160715/77e0603f/attachment.html>


More information about the swift-users mailing list