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 @Observable property wrapper and bump the CI to Xcode 11 / Swift 5.1 #762
Conversation
I'm working on fixing the CI after bumping to Xcode 11 |
ok, ready |
This is nice, just a couple of things:
|
The diff of this PR shows that the CI config hasn't been upgraded yet, but I'm happy to slit in into a separate PR. |
@petrpavlik very true and I am wrong. The fix for Xcode 11 and Swift 5.1 was only for the code, not the actual CI. This tipped me off in the wrong direction #739. |
@RuiAAPeres here's the separate travis PR #764 |
Regarding the other comments:
private class TestCounter {
@Observable private(set) var value: Int = 0
func increment() {
value += 1
}
}
|
I'd recommend relaxing |
This implementation still needs work to implement copy-on-write to avoid access control leakage. You can currently do this to get around the "private" mutability:
Which will update the existing wrapped property as well. |
Whats the status of this PR? Something like the |
Copy-on-write is generally inapplicable to any push based streams — each stream somewhat represents a unique topic, and subscribers hook into a specific unique topic. Therefore, copying becomes an alien concept to them because of the uniqueness constraint. For example, what should happen to the existing subscribers, when a new value is sent through different copies of the same origin? Depending on the answer, we have outcomes varying from "might as well keep it as reference type" to "unimplementable in today's Swift". Alternatively, we can strive to replicate the Combine In any case, it isn't fair that progress on this front has been stuck, and that our user base cannot enjoy the improved brevity of property wrapper. So I've proposed a substitute (#781) that need not wait on the said design & maintenance decisions. |
I guess this issue was resolved by #781? Should the PR be closed? |
@mluisbrown I really like #781, but there's a catch. My view models generally look like this class ViewModel {
private(set) lazy var profile = Property<Profile>(mutableProfile)
private let mutableProfile: MutableProperty<Profile>
init(profile: Profile) {
mutableProfile = MutableProperty<Profile>(profile)
}
} this provide compiler guarantees that no code outside of the view model can assign a value to class ViewModel {
@MutableProperty private(set) var count: Int = 0
}
let vm = ViewModel()
// vm.count = 0 // won't compile
vm.$count.value = 1 // will compile As much as I'd love to migrate my code to this since it'd make things much simpler, I'm not willing to do it at the expense of losing this compile-time guarantee. My PR had this handled by only exposing |
@petrpavlik you're implementation also has the same problem with private mutability, albeit by a more convoluted route as pointed out in @robertjpayne 's comment: You can do: var observable = self.viewModel.$profile.projectedValue
observable.wrappedValue = newProfile |
Ah, sorry, I missed that comment. Yeah, I'm happy to close this PR and bring up that access control leakage in a separate issue. |
Checklist
turn this
into this
usage