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:
- 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.
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.
精彩评论