Eyal
Eyal

Reputation: 10828

Core data - info about to-many relationship properties

Im a newbie to Core Data, im building kind of a music library app that has two tabs:
songs and artists tab that shows a list of artists with each artist total songs count and overall song duration (again thats for each artist row)

My core data objects:

Song
=====
name
duration
album

artist (to one relationship)


Artist
======
name

songs (to many relationship)

So fo now i can managed to show a list of artists, and each artist his total num of songs:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // i know i should reuse the cells..
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];

    Artist *artist = [self.fetchedResultsController objectAtIndexPath:indexPath];

    cell.textLabel.text = [NSString stringWithFormat:@"%@ %lu", artist.name, (unsigned long)artist.songs.allObjects.count];

    return cell;
}

I have two questions:

  1. Is that the right way to fetch the total songs for each artist? when i call artist.songs.allObjects.count does core data fetch all the songs? because i really don't need the songs objects..
  2. like i said i also need each artist to have the total duration for all its songs, how can i get that? (again without loading all the song objects)

Upvotes: 1

Views: 156

Answers (1)

Mundi
Mundi

Reputation: 80273

First, you should not worry about what Core Data does in the background in terms of fetching when you access relationships. Especially in connection with a fetched results controller Core Data will find the best combination of performance and memory footprint. Maybe this is the whole point about having an object graph rather than a relational database.

Still it would be maybe better to skip allObjects and to simply call more concisely

artists.songs.count

Second, for the duration calculation you can take advantage of the fact that all managed objects are key value coding compliant. You can use collective operators like this:

NSNumber *totalDuration = [artist.songs valueForKeyPath:@"@sum.duration"];

Again, the Core Data framework will make sure you get very efficient and performant code.

Upvotes: 2

Related Questions