Should Array's `append(_)` functions cause the array's `didSet`?
In my own test, it did call `didSet` in Playground. But in .swift files, it
didn't call.
Is this a known bug or something? Which is correct?
Xcode Version 9.0 beta 2 (9M137d)
swift --version
Apple Swift version 4.0 (swiftlang-900.0.45.6 clang-900.0.26)
It definitely should. Can you show the code where it wasn’t being called?
Thanks!
Jordan
···
On Jul 7, 2017, at 00:31, Zhao Xin via swift-users <swift-users@swift.org> wrote:
Should Array's `append(_)` functions cause the array's `didSet`?
In my own test, it did call `didSet` in Playground. But in .swift files, it didn't call.
Is this a known bug or something? Which is correct?
Xcode Version 9.0 beta 2 (9M137d)
swift --version
Apple Swift version 4.0 (swiftlang-900.0.45.6 clang-900.0.26)
Target: x86_64-apple-macosx10.9
let keysAndValues:Dictionary<String,String> = ["c":"c", "b":"b", "a":"a"]
var foo = Foo(keysAndValues: keysAndValues) // `let foo` is the same result
foo.keys.forEach { print($0) }
/*
prints
z
y
x
b
c
a
*/
Above code doesn't call `didSet` in playground. My .swift file is similar
and didn't call `didSet` either. However, if without a struct, `didSet` is
called.
var keys = ["z","y","x"]
{
didSet {
keys.sort()
}
}
let keysAndValues:Dictionary<String,String> = ["c":"c", "b":"b", "a":"a"]
keys.append(contentsOf: keysAndValues.keys)
keys.forEach { print($0) }
/*
prints
a
b
c
x
y
z
*/
*Xcode 9.0 beta 2 (9M137d)*
*Apple Swift version 4.0 (swiftlang-900.0.45.6 clang-900.0.26)*
*Target: x86_64-apple-macosx10.9*
*macOS Sierra 10.12.5 (16F73)*
Zhao Xin
···
On Fri, Jul 7, 2017 at 11:52 PM, Jordan Rose <jordan_rose@apple.com> wrote:
It definitely should. Can you show the code where it wasn’t being called?
Thanks!
Jordan
On Jul 7, 2017, at 00:31, Zhao Xin via swift-users <swift-users@swift.org> > wrote:
Should Array's `append(_)` functions cause the array's `didSet`?
In my own test, it did call `didSet` in Playground. But in .swift files,
it didn't call.
Is this a known bug or something? Which is correct?
Xcode Version 9.0 beta 2 (9M137d)
swift --version
Apple Swift version 4.0 (swiftlang-900.0.45.6 clang-900.0.26)
Target: x86_64-apple-macosx10.9
Above code doesn't call `didSet` in playground. My .swift file is similar and didn't call `didSet` either. However, if without a struct, `didSet` is called.
“If you don’t need to compute the property but still need to provide code that is run before and after setting a new value, use willSet and didSet. The code you provide is run any time the value changes outside of an initializer.”
Thank you very much Marco. But What is “outside of an initializer” really
bothers me. **Both** `func bar(keysAndValues:Dictionary<String, String>)`
works now. **Are they really outside ?**
>
> Above code doesn't call `didSet` in playground. My .swift file is
similar and didn't call `didSet` either. However, if without a struct,
`didSet` is called.
“If you don’t need to compute the property but still need to provide code
that is run before and after setting a new value, use willSet and didSet.
The code you provide is run any time the value changes outside of an
initializer.”
Uhhh, that is certainly not the results I’d have expected. Perhaps one of the swift language lawyers can explain.
···
On Jul 7, 2017, at 9:48 PM, Zhao Xin <owenzx@gmail.com> wrote:
Thank you very much Marco. But What is “outside of an initializer” really bothers me. **Both** `func bar(keysAndValues:Dictionary<String, String>)` works now. **Are they really outside ?**
The goal is that once the initializer is completed all accesses will go through the setter and therefore trigger willSet/didSet behavior. Since a local function can be assigned to a property or something and get called later, it has to go through the setter as well. So the rules only apply to what's directly in the body of the initializer, not anything nested. (This includes closures, even.) It might be worth a bug against us at Apple to make this more explicit in the documentation, https://bugreport.apple.com <Feedback Assistant.
On Jul 7, 2017, at 22:50, Marco S Hyman via swift-users <swift-users@swift.org> wrote:
On Jul 7, 2017, at 9:48 PM, Zhao Xin <owenzx@gmail.com> wrote:
Thank you very much Marco. But What is “outside of an initializer” really bothers me. **Both** `func bar(keysAndValues:Dictionary<String, String>)` works now. **Are they really outside ?**
Uhhh, that is certainly not the results I’d have expected. Perhaps one of the swift language lawyers can explain.
On Tue, Jul 11, 2017 at 2:29 AM, Jordan Rose <jordan_rose@apple.com> wrote:
On Jul 7, 2017, at 22:50, Marco S Hyman via swift-users < > swift-users@swift.org> wrote:
On Jul 7, 2017, at 9:48 PM, Zhao Xin <owenzx@gmail.com> wrote:
Thank you very much Marco. But What is “outside of an initializer” really
bothers me. **Both** `func bar(keysAndValues:Dictionary<String, String>)`
works now. **Are they really outside ?**
Uhhh, that is certainly not the results I’d have expected. Perhaps one of
the swift language lawyers can explain.
The goal is that once the initializer is completed all accesses will go
through the setter and therefore trigger willSet/didSet behavior. Since a
local function can be assigned to a property or something and get called
later, it has to go through the setter as well. So the rules only apply to
what's directly in the body of the initializer, not anything nested. (This
includes closures, even.) It might be worth a bug against us at Apple to
make this more explicit in the documentation, https://bugreport.apple.com.