iPhone OS Reference Library Apple Developer Connection spyglass button

NSFetchedResultsController Class Reference

Inherits from
Conforms to
Framework
/System/Library/Frameworks/CoreData.framework
Availability
Available in iPhone OS 3.0 and later.
Companion guide
Declared in
NSFetchedResultsController.h
Related sample code

Overview

This class is intended to efficiently manage the results returned from a Core Data fetch request to provide data for a UITableView object.

You use this class to populate cells in a UITableView object with objects fetched from Core Data. While table views can be used in several ways, this object is primarily intended to assist you with a master list view. UITableView expects its data source to provide cells as an array of sections made up of rows. You configure an instance of this class using a fetch request that specifies the entity, an array containing at least one sort ordering, and optionally a filter predicate. NSFetchedResultsController efficiently analyzes the result of the fetch request and computes all the information about sections in the result set, and for the index.

In addition, NSFetchedResultsController provides the following features:

A controller thus effectively has three modes of operation, determined by whether it has a delegate and whether the cache file name is set.

  1. No tracking: the delegate is set to nil.

    The controller simply provides access to the data as it was when the fetch was executed.

  2. Memory-only tracking: the delegate is non-nil and the file cache name is set to nil.

    The controller monitors objects in its result set and updates section and ordering information in response to relevant changes.

  3. Full persistent tracking: the delegate and the file cache name are non-nil.

    The controller monitors objects in its result set and updates section and ordering information in response to relevant changes. The controller maintains a persistent cache of the results of its computation.

Using NSFetchedResultsController

Creating the Fetched Results Controller

You typically create an instance of NSFetchedResultsController as an instance variable of a table view controller. You configure the controller with a fetch request, which must contain at least one sort descriptor to order the results. You can specify as the sectionNameKeyPath argument a key that the controller will use to split the results into sections, or pass nil to indicate that the controller should generate a single section. After creating an instance, you invoke performFetch: to actually execute the fetch.

NSManagedObjectContext *context = <#Managed object context#>;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Configure the request's entity, and optionally its predicate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"<#Sort key#>" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
[sortDescriptors release];
 
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]
        initWithFetchRequest:fetchRequest
        managedObjectContext:context
        sectionNameKeyPath:nil
        cacheName:@"<#Cache name#>"];
[fetchRequest release];
 
NSError *error;
BOOL success = [controller performFetch:&error];

The Controller’s Delegate

If you set a delegate for a fetched results controller, the controller registers to receive change notifications from its managed object context. Any change in the context that affects the result set or section information is processed and the results are updated accordingly. The controller notifies the delegate when result objects change location or when sections are modified (see NSFetchedResultsControllerDelegate). You typically use these methods to update the display of the table view.

Important: If you do not set a delegate, the controller does not monitor changes to objects in its associated managed object context. You may choose not to set a delegate if the results set will not change (if you are providing a read-only list, for example).

The Cache

Where possible, a controller uses a cache to avoid the need to repeat work performed in setting up any sections and ordering the contents. The cache is maintained across launches of your application.

When you initialize an instance of NSFetchedResultsController, you typically specify a cache name. (If you do not specify a cache name, the controller does not cache data.) When you create a controller, it looks for an existing cache with the given name:

Any time the section and ordering information change, the cache is updated.

If you have multiple fetched results controllers with different configurations (different sort descriptors and so on), you must give each a different cache name.

You can purge a cache using deleteCacheWithName:.

Implementing the Table View Datasource Methods

You ask the object to provide relevant information in your implementation of the table view data source methods:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [[<#Fetched results controller#> sections] count];
}
 
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[<#Fetched results controller#> sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
    UITableViewCell *cell = <#Get the cell#>;
    NSManagedObject *managedObject = [<#Fetched results controller#> objectAtIndexPath:indexPath];
    // Configure the cell with data from the managed object.
    return cell;
}
 
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[<#Fetched results controller#> sections] objectAtIndex:section];
    return [sectionInfo name];
}
 
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
    return [<#Fetched results controller#> sectionIndexTitles];
}
 
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
    return [<#Fetched results controller#> sectionForSectionIndexTitle:title atIndex:index];
}

Important: On iPhone OS 3.0, if you have a single section table view, there is an incompatibility between the values returned by NSFetchedResultsController and the values expected by UITableView. You can work around this incompatibility as follows:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
 
    NSUInteger count = [[<#Fetched results controller#> sections] count];
    if (count == 0) {
        count = 1;
    }
    return count;
}
 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 
    NSArray *sections = [<#Fetched results controller#> sections];
    NSUInteger count = 0;
    if ([sections count]) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section];
        count = [sectionInfo numberOfObjects];
    }
    return count;
}
This workaround is not required on iPhone OS 3.1 and later.

Responding to User-Driven Changes

In general, NSFetchedResultsController is designed to respond to changes at the model layer by informing its delegate when result objects change location or when sections are modified. If you allow a user to reorder table rows, then your implementation of the delegate methods must take this into account—see NSFetchedResultsControllerDelegate. There is also a limitation that NSFetchedResultsController does not support sections being deleted as a result of a UI-driven change.

Subclassing Notes

You create a subclass of this class if you want to customize the creation of sections and index titles. You override sectionIndexTitleForSectionName: if you want the section index title to be something other than the capitalized first letter of the section name. You override sectionIndexTitles if you want the index titles to be something other than the array created by calling sectionIndexTitleForSectionName: on all the known sections.

Tasks

Initialization

Configuration Information

Accessing Results

Querying Section Information

Configuring Section Information

Properties

For more about Objective-C properties, see “Properties” in The Objective-C Programming Language.

cacheName

The name of the file used to cache section information.

@property (nonatomic, readonly) NSString *cacheName
Discussion

The file itself is stored in a private directory; you can only access it by name using deleteCacheWithName:

Availability
Declared In
NSFetchedResultsController.h

delegate

The object that is notified when the fetched results changed.

@property(nonatomic, assign) id <NSFetchedResultsControllerDelegate> delegate
Special Considerations

If you do not specify a delegate, the controller does not track changes to managed objects associated with its managed object context.

Availability
Related Sample Code
Declared In
NSFetchedResultsController.h

fetchedObjects

The results of the fetch.

@property (nonatomic, readonly) NSArray *fetchedObjects
Discussion

Returns nil if performFetch: hasn’t been called.

Availability
Declared In
NSFetchedResultsController.h

fetchRequest

The fetch request used to do the fetching.

@property (nonatomic, readonly) NSFetchRequest *fetchRequest
Discussion

Typically the sort descriptor used in the request groups objects into sections.

Availability
Declared In
NSFetchedResultsController.h

managedObjectContext

The managed object context used to fetch objects.

@property (nonatomic, readonly) NSManagedObjectContext *managedObjectContext
Discussion

The controller registers to listen to change notifications on this context and properly update its result set and section information. 

Availability
Related Sample Code
Declared In
NSFetchedResultsController.h

sectionIndexTitles

The array of section index titles.

@property (nonatomic, readonly) NSArray *sectionIndexTitles
Discussion

The default implementation returns the array created by calling sectionIndexTitleForSectionName: on all the known sections. You should override this method if you want to return a different array for the section index.

Special Considerations

You only need this method if you use a section index.

Availability
Declared In
NSFetchedResultsController.h

sectionNameKeyPath

The key path on the fetched objects used to determine the section they belong to.

@property (nonatomic, readonly) NSString *sectionNameKeyPath
Availability
Declared In
NSFetchedResultsController.h

sections

The sections for the receiver’s fetch results.

@property (nonatomic, readonly) NSArray *sections
Discussion

The objects in the sections array implement the NSFetchedResultsSectionInfo protocol.

You typically use the sections array when implementing UITableViewDataSource methods, such as numberOfSectionsInTableView: and tableView:titleForHeaderInSection:.

Availability
Declared In
NSFetchedResultsController.h

Class Methods

deleteCacheWithName:

Deletes the cached section information with the given name.

+ (void)deleteCacheWithName:(NSString *)name

Parameters
name

The name of the cache file to delete.

If name is nil, deletes all cache files.

Availability
Declared In
NSFetchedResultsController.h

Instance Methods

indexPathForObject:

Returns the index path of a given object.

- (NSIndexPath *)indexPathForObject:(id)object

Parameters
object

An object in the receiver’s fetch results.

If object is not contained in the receiver’s fetch results, an exception is raised.

Return Value

The index path of object in the receiver’s fetch results.

Availability
  • Available in iPhone OS 3.0 and later.
Declared In
NSFetchedResultsController.h

initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:

Returns a fetch request controller initialized using the given arguments.

- (id)initWithFetchRequest:(NSFetchRequest *)fetchRequest managedObjectContext:(NSManagedObjectContext *)context sectionNameKeyPath:(NSString *)sectionNameKeyPath cacheName:(NSString *)name

Parameters
fetchRequest

The fetch request used to get the objects.

The fetch request must have at least one sort descriptor. If the controller generates sections, the first sort descriptor in the array is used to group the objects into sections; its key must either be the same as sectionNameKeyPath or the relative ordering using its key must match that using sectionNameKeyPath.

context

The managed object against which fetchRequest is executed.

sectionNameKeyPath

A key path on result objects that returns the section name. Pass nil to indicate that the controller should generate a single section.

The section name is used to pre-compute the section information.

If this key path is not the same as that specified by the first sort descriptor in fetchRequest, they must generate the same relative orderings. For example, the first sort descriptor in fetchRequest might specify the key for a persistent property; sectionNameKeyPath might specify a key for a transient property derived from the persistent property.

name

The name of the cache file the receiver should use. Pass nil to prevent caching.

Pre-computed section info is cached to a private directory under this name. If Core Data finds a cache stored with this name, it is checked to see if it matches the fetchRequest. If it does, the cache is loaded directly—this avoids the overhead of computing the section and index information. If the cached information doesn’t match the request, the cache is deleted and recomputed when the fetch happens.

Return Value

The receiver initialized with the specified fetch request, context, key path, and cache name.

Availability
  • Available in iPhone OS 3.0 and later.
Related Sample Code
Declared In
NSFetchedResultsController.h

objectAtIndexPath:

Returns the object at the given index path in the fetch results.

- (id)objectAtIndexPath:(NSIndexPath *)indexPath

Parameters
indexPath

An index path in the fetch results.

If indexPath does not describe a valid index path in the fetch results, an exception is raised.

Return Value

The object at a given index path in the fetch results.

Availability
  • Available in iPhone OS 3.0 and later.
Related Sample Code
Declared In
NSFetchedResultsController.h

performFetch:

Executes the receiver’s fetch request.

- (BOOL)performFetch:(NSError **)error

Parameters
error

If the fetch is not successful, upon return contains an error object that describes the problem.

Return Value

YES if the fetch executed successfully, otherwise NO.

Discussion

After executing this method, you can access the receiver’s the fetched objects with the property fetchedObjects.

Special Considerations

This method returns NO and if the fetch request doesn’t include a sort descriptor that uses the section name key path specified in initWithFetchRequest:managedObjectContext:sectionNameKeyPath:cacheName:.

Availability
  • Available in iPhone OS 3.0 and later.
Declared In
NSFetchedResultsController.h

sectionForSectionIndexTitle:atIndex:

Returns the section number for a given section title and index in the section index.

- (NSInteger)sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)sectionIndex

Parameters
title

The title of a section

sectionIndex

The index of a section.

Return Value

The section number for the given section title and index in the section index

Discussion

You would typically call this method when executing UITableViewDataSource’s tableView:sectionForSectionIndexTitle:atIndex: method.

Availability
  • Available in iPhone OS 3.0 and later.
Declared In
NSFetchedResultsController.h

sectionIndexTitleForSectionName:

Returns the corresponding section index entry for a given section name.

- (NSString *)sectionIndexTitleForSectionName:(NSString *)sectionName

Parameters
sectionName

The name of a section.

Return Value

The section index entry corresponding to the section with name sectionName.

Discussion

The default implementation returns the capitalized first letter of the section name.

You should override this method if you need a different way to convert from a section name to its name in the section index.

Special Considerations

You only need this method if you use a section index.

Availability
  • Available in iPhone OS 3.0 and later.
Declared In
NSFetchedResultsController.h


Last updated: 2009-09-09

Did this document help you? Yes It's good, but... Not helpful...