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

Zhao Xin owenzx at gmail.com
Thu Jul 14 19:22:13 CDT 2016


I think the problem is that you should not call callback?() in didSet() as
the values in the closure are updated depending on the function, which
means, it is not updated until the didSet() function finished.


Zhaoxin


On Fri, Jul 15, 2016 at 6:17 AM, Diego Sánchez <diego.sanchezr at gmail.com>
wrote:

> 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/035b761f/attachment.html>


More information about the swift-users mailing list