Post AQJbOpMFf4VpBnm3EW by shadowfacts@social.shadowfacts.net
(DIR) More posts by shadowfacts@social.shadowfacts.net
(DIR) Post #AQJXV6Qehm1Q3TZRse by nicklockwood@mastodon.social
2022-12-06T00:18:18Z
0 likes, 0 repeats
If anything should put paid to the idea that properties in Swift imply O(1) performance it should be the fact that SwiftUI views have a computed body property rather than a render() method.
(DIR) Post #AQJXV7R2xnvfAylH84 by nicklockwood@mastodon.social
2022-12-06T00:21:23Z
0 likes, 0 repeats
I've long argued that the meaning of properties vs methods should be considered purely semantic (has-a vs produces-a), but tbh even I would have probably balked at hiding something as expensive as generating an entire subview tree behind a property interface before seeing Apple embrace it in SwiftUI.
(DIR) Post #AQJXV81CnMquz7g9UO by davemurdock@mastodon.online
2022-12-06T00:27:23Z
0 likes, 0 repeats
@nicklockwood completely agree with your semantics and I’m still gobsmacked at the convention smashing ‘body’ property. I mean sure it feels like body()….hmm, is ‘body’ technically effect free? That use to be one of the property vs. parameterless function signals…
(DIR) Post #AQJXV8dqThlEuxl0iW by nicklockwood@mastodon.social
2022-12-06T00:32:44Z
0 likes, 0 repeats
@davemurdock I'm not sure even effect-free is guaranteed - e.g. if it returns a random result (thereby incrementing the underlying RNG sequence), or memoizes some expensive value into a shared cache.But yeah in general you'd hope properties would have at least some degree of idempotence to them.
(DIR) Post #AQJXV9FmCg6OobVIq8 by cocoaphony@mastodon.social
2022-12-06T00:36:14Z
0 likes, 0 repeats
@nicklockwood @davemurdock wouldn’t that break SwiftUI? I was pretty sure a key rule is that body doesn’t change; it’s a pure value. State impacts how it’s rendered, but it shouldn’t change its value.
(DIR) Post #AQJXVA1dKkNpD1tWQy by shadowfacts@social.shadowfacts.net
2022-12-06T01:12:13.948589Z
0 likes, 0 repeats
@cocoaphony @nicklockwood @davemurdock it _should_ be pure, but it's not a hard and fast rule. it warns about @State changes since that could cause a render/update loop, but anything that's not part of SwiftUI's state tracking system I think is technically okaydoing .background(arrayOfColors.randomElement()!) is a useful, very not-pure trick for making sure state changes don't trigger wider view updates than expected
(DIR) Post #AQJXVBtYNl6n0Y867M by nicklockwood@mastodon.social
2022-12-06T00:24:37Z
0 likes, 0 repeats
That said, while property-vs-method may not be the right mechanism to convey a cheap vs expensive operation, it would be nice if there were some simple convention for this.I suppose moving forward it will probably be conveyed by marking all expensive methods as async - although there are sometimes valid reasons for having lengthy operations that are synchronous.
(DIR) Post #AQJYs7Up0GI3yn3hfk by davemurdock@mastodon.online
2022-12-06T01:19:31Z
1 likes, 0 repeats
@shadowfacts @cocoaphony @nicklockwood that’s a good idea!
(DIR) Post #AQJZpCOQRMfGFhEokq by cocoaphony@mastodon.social
2022-12-06T01:22:25Z
0 likes, 0 repeats
@shadowfacts @davemurdock @nicklockwood the only confusion here is whether referencing .body counts as “a render/update loop.” I’m guessing that the SwiftUI folks have realized they we won’t follow the rules and have coded very defensively in a way that makes that work out, but it doesn’t change the rules.I think there’s a (non-random) reason randomElement is a method, not a property.
(DIR) Post #AQJZpD2q16zUH295kG by shadowfacts@social.shadowfacts.net
2022-12-06T01:38:17.386403Z
0 likes, 0 repeats
@cocoaphony @davemurdock @nicklockwood I don't think there's any way to trigger a loop without modifying state or mutating a global var (aside from the trivial `var body: some View { AnyView(self.body) }`)? Unless I'm misunderstanding what you're sayingI'm not sure the framework needs to be particularly defensive about this? Even if some external event causes the result of body to change the next time it's evaluated, the body won't be evaluated again until there is some State change that SwiftUI does observe—at which point, there's no difference between the changes being triggered externally versus within the framework-tracked data model
(DIR) Post #AQJbOoiY2gklCfCLLc by cocoaphony@mastodon.social
2022-12-06T01:51:42Z
0 likes, 0 repeats
@shadowfacts @davemurdock @nicklockwood I mean the other way around. There’s no promise that the only reason that “body” is accessed is for re-render, or that it will accessed exactly once per render loop. I expect this happens to be true, however.
(DIR) Post #AQJbOpMFf4VpBnm3EW by shadowfacts@social.shadowfacts.net
2022-12-06T01:55:56.800135Z
0 likes, 0 repeats
@cocoaphony @davemurdock @nicklockwood Ah, yeah, I think you're right. I don't think there's any reason for it to, but the framework _could _ access .body outside of a view update, so non-pure code shouldn't rely on that assumption
(DIR) Post #AQJneC7EWuCnZ5qLo0 by davemurdock@mastodon.online
2022-12-06T04:00:15Z
1 likes, 0 repeats
@shadowfacts @cocoaphony @nicklockwood IIRC this WWDC ‘20 session Data Essentials in SwiftUI sounds kind of dry, there's a big chunk of stuff about the view rendering lifecycle & the importance keeping your views lightweight, with this statement germane to the discussion “A view's body should be a pure function, free of side effects.” https://developer.apple.com/wwdc20/10040