开发者

Sections from already queried Entity

So i'm displaying some Entities in a UITableView. With clicking on a Cell i want to show other Entities that are already queried in a "to-many" Relationship.

For example i'm displaying all Classes of a School. Now i want to display all Students of a Class. This Students are already available as an NSSet under Class.students

Now i want to display the Students in different Sections following by their first Letter.

If i wanted to get them direct开发者_如何学Pythonly from CoreData, i would do something like

// init fetch request
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Student" inManagedObjectContext:self.managedObjectContext];

// Search only specific students
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"class == %@", theClassThoseStudentsBelongTo];
[fetchRequest setPredicate:predicate];

// Generate it
NSFetchedResultsController *theFetchedResultsController = 
    [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                        managedObjectContext:self.managedObjectContext 
                                          sectionNameKeyPath:@"firstLetter" 
                                                   cacheName:@"StudentTable"];

with this method i would get them nicely arranged into sections.

But i already have all students for a specific Class. is there a way to init a NSFetchedResultsController with a initialized NSSet or to do something equal?

Sure, i could arrange my NSSet manually but isn't there such a nice way like it is for a new query?

thanks in advance. Please leave a comment if something is unclear.


I guess you only have 2 options: using NSFetchedResultsController or sorting the objects on your own.

NSFetchedResultsController & NSPredicate:
Pros: easy object deletition; notifications of model changes, e.g. during syncing
Cons: unnecessary refetch

NSSet & NSSortDescriptor
Pros: no refetch Cons: complicated deletition; no notifications of model changes, e.g during syncing: you could be displaying a student that has already been deleted


you could use a NSPredicate which uses the reverse relationship (from your students back to the class)

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
...

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"class == %@", theClassThoseStudentsBelongTo];
[fetchRequest setPredicate:predicate];

NSFetchedResultsController *theFetchedResultsController = ...


The relationship of objects fetched by NSFetchedResultsController start out as faults and are only fetched when needed. This means that if we don't use the "Student" entities for the first tableView it will be lazily loaded only when we need it.

However, since you need to know the count of students the situation is a little more complicated since calling [class.students count] will fire the fault. (Calling the KVO @count will fire the fault also).

So you have two options:

  1. managed an attribute called studentsCount in class that reflects the number of entities in students. Calling this attribute will not fire a fault on the relationship.
  2. use countForFetchRequest:

    NSFetchRequest *req = [[NSFetchRequest alloc] init];
    [req setEntity:[NSEntityDescription entityForName:@"Student" inManagedObjectContext:context]];
    [req setPredicate:[NSPredicate predicateWithFormat:@"class = %@", myClass]];
    

The second option performs a fetch, but a very efficient one, so maybe it's efficient enough - i didn't do performance tests so i can't really say.

By the way, if you're not sure whether or not the relationship fired a fault you can use the method hasFaultForRelationshipNamed.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜