Core Data derived attributes don't appear to work until/unless the context is refreshed

WWDC 2019 Session 230 (Making Apps with Core Data) introduced a new Core Data feature, derived attributes. In a demo of the feature a postCount attribute was added to an entity, with the derived expression of "posts.@count". As far as I can tell the demo only worked because the context was "fresh". If you make any changes to a context, derived expressions yield stale results, even after the context is saved. Only a call to context.refreshAllObjects() (or context.reset()) refreshes them. To state that a bit differently, using the demo's example: tag.posts.count yields a correct value after context.save(), but tag.postCount does not. Until, that is, you call context.refreshAllObjects(). Or context.reset().


I filed a bug, together with a sample app.

Post not yet marked as solved Up vote post of mul Down vote post of mul
1.9k views

Replies

Just adding a little more detail...


Not surprising: Rather than calling context.refreshAllObjects() you could just call context.refresh(), passing in the object whose derived attribute you're about to access.


Surprising: Acquiring an object via an NSFetchRequest doesn't refresh its derived attributes.


(The second is surprising to me because I thought that an NSFetchRequest guaranteed a trip all the way to the store—which is, you might think, a kind of refresh.)

Fetching goes to the store to determine which objects match the request. It doesn't refresh the attributes unless you are using "shouldRefreshRefetchedObjects". And I've found that option doesn't actually work (FB6161838). Derived attributes are now documented here: https://developer.apple.com/documentation/coredata/nsderivedattributedescription

Can I ask you a favor? When I try to add more than one derived attribute to any entity, and then insert an object into that entity, I get a SIGABRT error with no reason. I have tried for an entire day to solve this.


I first create a new version of the

xcdatamodel
with two new attributes in Entity A. Each of those attributes is a boolean, and is set as
derived
and
optional
. Each references an
optional
boolean on Entity B. None of the attributes on either entity is set as
scalar
. For each new derived attribute the derivation is basically a simple, to-one keypath to an object on Entity B. When I add just one of the new attributes - either one - the app functions fine. As soon as I add another attribute, the app crashes on inserting a new object into Entity A. Expanding on this, I find that adding more than one derived attribute at all to any entity is causing a crash upon inserting a new object into that entity.

The error is simply

Thread 1: signal SIGABRT

with no reason given.


This seems like crazy behavior to me. Is anyone else having an issue like this? Or do you have an idea of why I might be having this issue?