Open tgrapperon opened 1 year ago
I used print statements to verify that state is indeed being mutated as one would expect. Since the reducer is not recognizing that anything changed at all, that leads me to believe that Fetched<ManagedObject>
itself is having an issue with equatability. What's interesting is that there is never an instance when Fetched
actually conforms to the Equatable
protocol, but the compiler would complain when I try to explicitly conform it myself. Turns out that Hashable
conforms to Equatable
, so because Fetched
conforms to Hashable
, it will automatically conform to Equatable
. I don't see any explicit overloading of ==
, so Fetched
must be relying on whatever the compiler automatically generates for us.
What I also find odd is that print(state.todo.first)
shows me this:
Fetched(
id: _NSCoreDataTaggedObjectID(),
context: NSManagedObjectContext(),
viewContext: NSManagedObjectContext(↩︎),
token: nil
)
So strange that I don't see the object
property in there, which is what holds the actual value of interest. Could it be that the synthesized version is doing a comparison of something like this?
extension Fetched: Equatable {
public static func == (lhs: Fetched, rhs: Fetched) -> Bool {
return lhs.id == rhs.id &&
lhs.context == rhs.context &&
lhs.viewContext == rhs.viewContext &&
lhs.token == rhs.token
}
}
That would certainly explain why despite mutating state, the reducer is not actually sending updates to ViewStore
.
Oh fascinating! Looking through the Swift proposal SE-0185 relating to synthesizing Equatable
and Hashable
conformance, computed properties are completely ignored:
Synthesized requirements for structs For a struct, synthesis of P's requirements is based on the conformances of only its stored instance properties. Neither static properties nor computed instance properties (those with custom getters) are considered.
Something tells me it's not a coincidence that the very property we need to check for equatability might be excluded from whatever the Swift compiler synthesizes for us ;)
Oh no :( :( :( object
as a reference type makes this so messy...you have two value types Fetched
being compared, but if object
is a reference type, then by the time we test for equatability, the mutation that occurred in one of the Fetched
value types will be seen in the other. I have no clue how to work around that...
Discussed in https://github.com/tgrapperon/swift-dependencies-additions/discussions/67