In my core data model, a Person
has one or more Cars
, specified by the unordered to-many relationship 'Cars'. Frequently, I need to retrieve a Person's cars ordered by datePurchased
, or by dateLastUsed
.
Until now, I have been adding my own method to Person
for carsByDatePurchased
. This uses a sort descriptor to sort the NSSet cars
and return an NSArray.
Could/should I instead use a Fetched Property for this? I am experiencing some performance overhead using the sort descriptor every time I need the cars in a certain order, even going so far as implementing my own caching of carsByDatePurchased
. It looks like the fetched property is cached for me - is that correct?
What are the limitations of a fetched property vs my own implementation?
And crucially, does the fetched property's value persist between executions? If I update the fetched property and save my context, is the value stored for the next time I launch the application?
Inverse relationships enable Core Data to propagate change in both directions when an instance of either the source or destination type changes. Every relationship must have an inverse. When creating relationships in the Graph editor, you add inverse relationships between entities in a single step.
Transient attributes are properties that you define as part of the model, but that are not saved to the persistent store as part of an entity instance's data. Core Data does track changes you make to transient properties, so they are recorded for undo operations.
Core Data is the M in MVC, the model layer of your application. Even though Core Data can persist data to disk, data persistence is actually an optional feature of the framework. Core Data is first and foremost a framework for managing an object graph.
A description of search criteria used to retrieve data from a persistent store.
A fetched property will work, and indeed I used it in my own project with a Post->Comment relationship which needs to be sorted by 'date added index'.
There are a number of caveats: You cannot specify a sort descriptor in the visual editor and have to specify it in code.
I use something like this
// Find the fetched properties, and make them sorted...
for (NSEntityDescription *entity in [_managedObjectModel entities])
{
for (NSPropertyDescription *property in [entity properties])
{
if ([property isKindOfClass:[NSFetchedPropertyDescription class]])
{
NSFetchedPropertyDescription *fetchedProperty = (NSFetchedPropertyDescription *)property;
NSFetchRequest *fetchRequest = [fetchedProperty fetchRequest];
// Only sort by name if the destination entity actually has a "index" field
if ([[[[fetchRequest entity] propertiesByName] allKeys] containsObject:@"index"])
{
NSSortDescriptor *sortByName = [[NSSortDescriptor alloc] initWithKey:@"index"
ascending:YES];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sortByName]];
}
}
}
}
In My Post entity I have a fetched property called "sortedComments" which is defined as:
post == $FETCH_SOURCE
where posts have a to-many "comments" relationship and comments have a "post" inverse
In opposition to the other answers here: The benefits of using a fetched property like this, is CoreData takes care of the caching and invalidating the cache as comments for a post or indeed the post that owns them changes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With