klaussner
klaussner

Reputation: 2374

How to manage a to-many relationship in Core Data?

I'm new to Core Data on the iPhone and have a few questions about to-many relationships.

The data model contains two objects Movie and Comment. A Movie contains an NSSet of Comments. I want to display all Movies in a table view. When the user taps on a cell, the app navigates to another table view that displays all corresponding comments.

  1. Question: I want the comments to be sorted by date, but the NSSet is unordered. Of course, I can create an array from the set and sort it in memory, but wouldn't it be more efficient if the SQLite database would do the sorting?

  2. Question: After retrieving the array of Movies, each one has a an empty NSSet that is filled with data on first access. This happens when the list of comments is displayed. But what happens when the user goes back to the movie list? The comments of the movie that was displayed before are no longer needed. Does Core Data keep all the 'on-demand' entities in memory?

Thanks in advance.

Upvotes: 1

Views: 521

Answers (2)

Kentzo
Kentzo

Reputation: 3961

  1. You can use NSFetchRequest.

    
    NSFetchRequest *request = [NSFetchRequest new];
    [request setEntity:aCommentEntity];
    [request setSortDescriptors:sortDescriptors];
    [request setPredicate:[NSPredicate predicateWithFormat:@"movie = %@", aMovie]];
    NSArray *comments = [managedObjectContext executeFetchRequest:request error:&error];
    
    Also take a look at NSFetchedResultsController

  2. Core Data uses smart mechanism called faulting: Faulting and Uniquing

Upvotes: 3

TechZen
TechZen

Reputation: 64428

Of course, I can create an array from the set and sort it in memory, but wouldn't it be more efficient if the SQLite database would do the sorting?

No, because that would require the persistent store to keep sorting info for every conceivable sort. Since sorts are highly variable depending on immediate needs, it is better if sorting is done at the level of the view controller or the equivalent.

You can use a fetch to handle this as suggest by Kentzo, however, if you already have the Movie object you already have the Comment objects you want so you can just use NSSet's sortedArrayUsingDescriptors: to create the sorted array for you.

MovieMO *aMovie=//...get the Movie object
NSSortDescriptor *aSort=[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]
NSArray *sortedComments=[aMovie.comments sortedArrayUsingDescriptors:aSort];

In the normal Master-Detail view setup, you would select a Movie object in the Master view and then pass that object to Detail view controller. The Detail view controller would then walk the Movie.comments relationship to get the comments which it would then sort for display.

This method works well for most apps. If you have thousands of comments per movie, then might need to use a fetch and/or a fetched results controller.

Upvotes: 2

Related Questions