Lazy loading of Shared initial values #3060
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Extends PR #3057 to include initial values in addition to default values.
Persistent Shared values are often declared with an initial value.
This initial value is eagerly evaluated and passed to the Shared initializer. When there's an existing reference, this initial value is thrown away. For simple types like the one above, this isn't a problem. However, when the initial value is more complex, it can be wasteful if the Shared value is declared in many features of an app.
More significantly, the initial value may have side effects. For example, consider a
Folder
model that creates aUUID
id using theuuid
dependency. If you want to persist theFolder
, you would declare aPersistenceKey
.Your feature declares the shared folder in its state.
Now you want to override that root folder in a test.
Because the
Feature.State
initializer evaluated theFolder
declaration, theuuid
was incremented. The value was thrown away because the Shared value in the dependencies block already created the reference, but the side effect still happened.This PR makes that initial value load lazily so there are no side effects unless the value is actually needed. State initializers and local declarations are more efficient, and tests are deterministic.