Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fetched Property in Core Data

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?

like image 680
Ben Packard Avatar asked Oct 22 '12 17:10

Ben Packard


People also ask

What are relationships in Core Data?

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.

What is transient in Core Data?

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.

What is Core Data a feature of?

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.

What is Nsfetchrequest?

A description of search criteria used to retrieve data from a persistent store.


1 Answers

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.

like image 180
Tony Million Avatar answered Sep 19 '22 09:09

Tony Million