< Previous PageNext Page > Hide TOC

Fetching Managed Objects

This article describes how to fetch managed objects and discusses some considerations for ensuring that fetching is efficient.

Contents:

Fetching Managed Objects
Retrieving Specific Objects
Fetching and Entity Inheritance


Fetching Managed Objects

You fetch managed objects by sending a fetch request to a managed object context. You first create a fetch request. As a minimum you must specify an entity for the request. You can get the entity from your managed object model using the NSEntityDescription method entityForName:inManagedObjectContext:. You may also set a predicate (for details about creating predicates, see Predicate Programming Guide), sort descriptors, and other attributes if necessary. You retrieve objects from the context using executeFetchRequest:error:, as illustrated in the example below.

Listing 1  Example of creating and executing a fetch request

NSManagedObjectContext *moc = [self managedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription
    entityForName:@"Employee" inManagedObjectContext:moc];
NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
[request setEntity:entityDescription];
 
// Set example predicate and sort orderings...
NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
    @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];
[request setPredicate:predicate];
 
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
    initWithKey:@"firstName" ascending:YES];
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[sortDescriptor release];
 
NSError *error = nil;
NSArray *array = [moc executeFetchRequest:request error:&error];
if (array == nil)
{
    // Deal with error...
}

Note that you cannot fetch using a predicate based on transient properties (although you can use transient properties to filter in memory yourself). Moreover, It is also important to note that there are some interactions between fetching and the type of store—for details, see “Store Types and Behaviors.” To summarize, though, if you execute a fetch directly, you should typically not add Objective-C-based predicates or sort descriptors to the fetch request. Instead you should apply these to the results of the fetch. If you use an array controller, you may need to subclass NSArrayController so you can have it not pass the sort descriptors to the persistent store and instead do the sorting after your data has been fetched.

If you use multiple persistence stacks in your application, or if multiple applications might access (and modify) the same store simultaneously, fetching is also important in ensuring that data values are current —see “Ensuring Data Is Up-to-Date.”

Retrieving Specific Objects

If your application uses multiple contexts and you want to want to test whether an object has been deleted from a persistent store, you can create a fetch request with a predicate of the form self == %@. The object you pass in as the variable can be either a managed object or a managed object ID, as in the following example:

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
NSEntityDescription *entity =
    [NSEntityDescription entityForName:@"Employee"
            inManagedObjectContext:managedObjectContext];
[request setEntity:entity];
 
NSPredicate *predicate =
    [NSPredicate predicateWithFormat:@"self == %@", targetObject];
[request setPredicate:predicate];
 
NSError *error = nil;
NSArray *array = [managedObjectContext executeFetchRequest:request error:&error];
if (array != nil) {
    int count = [array count]; // may be 0 if the object has been deleted
    // …
}
else // deal with error…

The count of the array returned from the fetch will be 0 if the target object has been deleted. If you need to test for the existence of several objects, it is more efficient to use the IN operator than it is to execute multiple fetches for individual objects, for example:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"self IN %@",
                                            arrayOfManagedObjectIDs];

Fetching and Entity Inheritance

If you define an entity inheritance hierarchy (see “Entity Inheritance”), when you specify a super-entity as the entity for a fetch request, the request returns all matching instances of the super-entity and of sub-entities. In some applications, you might specify a super-entity as being abstract (see “Abstract Entities”). To fetch matching instances of all concrete sub-entities of the abstract entity, you set the entity for fetch specification to be the abstract entity. In the case of the domain described in “Abstract Entities,” if you specify a fetch request with the Graphic entity, the fetch returns matching instances of Circle, TextArea, and Line.



< Previous PageNext Page > Hide TOC


© 2004, 2009 Apple Inc. All Rights Reserved. (Last updated: 2009-03-04)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.