-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Add didSet/willSet recursion change to the changelog #15526
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add didSet/willSet recursion change to the changelog #15526
Conversation
Please mention that this only happens in Swift 5 mode. (Being in the Swift 5 section isn't enough to imply that.) |
be05e5d
to
17407a8
Compare
In swiftlang#15280 we changed the behaviour of setting a property within its own `didSet` or `willSet` observer, such that we only perform direct accesses on `self` in Swift 5 mode. This commit adds this to the changelog and, in addition, does some gardening for the SR links.
17407a8
to
96c3296
Compare
@swift-ci Please smoke test and merge |
@jrose-apple Looks like that didn't trigger the bot for some reason; could you please try again? |
@swift-ci Please smoke test and merge |
@jrose-apple This and #15280 causes strange results in Swift 4.2. You fell in infinite loop in a lot of strange cases. |
@afshinpir This change is unrelated to the behaviour that you're experiencing in your Stack Overflow question – you'd also get the same behaviour in Swift 4.1. Whether or not a property is accessed directly (without triggering observers) is determined statically by the context in which the access is performed, rather than being determined dynamically by whether or not it's taking place during a call to a given function. The current behaviour (up until Swift 5 mode) is to always perform a direct access when accessing a property within its own However in either case, a property access done within an instance method will not be done directly, which is the behaviour you're observing. |
@hamishknight But when we are setting property within its own didSet, I think it should not trigger even if we are using an instance method. Assume there is a lot of codes in didSet and we want to organize them into few methods. If there is a decision not to trigger didSet when we set property inside it, I think it should be similar in all cases, either with setting it inside didSet itself or by calling another function. And as a suggestion, maybe it is better that trigger didSet or not depend on type data. For example, does not trigger for reference types and trigger it for value types. |
Meta-comment: this sort of discussion is better held on the forums at https://forums.swift.org. Other interested parties won't know to look here. |
Sorry, I was going to reply to this sooner but never got around to it. As Jordan says, this discussion would be better placed on the Swift forums. In addition, I'm pretty sure such a change would need to go through evolution. In short though, my personal feeling is that such a change isn't worth the complexity. I don't think having to split observer implementations up into multiple methods such that those methods need direct access to storage is that common of an occurrence. It's worth noting you can always forward on direct-to-storage access using an struct S {
var i: Int = 0 {
didSet {
doSomething(&i)
}
}
private func doSomething(_ i: inout Int) {
// Work with `i` direct-to-storage.
}
} In addition, if needed you can always desugar an observable stored property into a computed property backed by storage, which gives you precise control over when you want the observer to be called. |
In #15280 we changed the behaviour of setting a property within its own
didSet
orwillSet
observer, such that we only perform direct accesses onself
in Swift 5 mode.This commit adds this to the changelog and, in addition, does some gardening for the SR links.