I have an app that saves data to a Core Data sql then view it in a tableView. And I'm trying to add a searchBar to search through the data.
I created two NSFetchedResultsController. One for getting entity data and the other for getting entity data after filtering using NSPredicate.
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack DefaultStack];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"offer" inManagedObjectContext:coreDataStack.managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:NO]];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:#"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (NSFetchedResultsController *)fetchedSearchResultsController{
if (_fetchedSearchResultsController != nil) {
return _fetchedSearchResultsController;
}
CoreDataStack *coreDataStack = [CoreDataStack DefaultStack];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"offer" inManagedObjectContext:coreDataStack.managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:NO]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"location contains[c] %#", self.searchDisplayController.searchBar.text];
[fetchRequest setPredicate:predicate];
_fetchedSearchResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:#"sectionName" cacheName:nil];
_fetchedSearchResultsController.delegate = self;
return _fetchedSearchResultsController;
}
And showing data in each cell by cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];//] forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Entry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
Entry *searchEntry = [self.fetchedSearchResultsController objectAtIndexPath:indexPath];
NSString *recipe = nil;
if (tableView == self.searchDisplayController.searchResultsTableView) {
cell.textLabel.text = searchEntry.location;
} else {
cell.textLabel.text = entry.location;
}
return cell;
}
But I get this error: *'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'*
When I comment [fetchRequest setPredicate:predicate]; out, I don't get the error anymore. So I'm assuming the error is coming from predicate but I don't know how to overcome it.
Entry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
Entry *searchEntry = [self.fetchedSearchResultsController objectAtIndexPath:indexPath];
first check for entry and searchEntry wether returning null or not ?
Related
This is my datamodel
In my TableView, I want to display first and city
The following is my code where I fetch them. I'm getting the first data but not the city:
-(NSFetchedResultsController *)fetchedResultsController
{
if(fetchedResultsController != nil)
{
return fetchedResultsController;
}
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entityPerson = [NSEntityDescription entityForName:#"Person" inManagedObjectContext:context];
[request setEntity:entityPerson];
NSSortDescriptor *sortName = [[NSSortDescriptor alloc] initWithKey:#"first" ascending:YES];
NSSortDescriptor *sortAddress = [[NSSortDescriptor alloc] initWithKey:#"address.city" ascending:NO];
request.sortDescriptors = #[sortAddress, sortName];
[request setFetchBatchSize:50];
NSFetchedResultsController *fetchedResults = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
fetchedResultsController = fetchedResults;
fetchedResultsController.delegate = self;
return fetchedResultsController;
}
This is where i fetch the results and following is where i try to display the fetched results
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
TableCell *cell = (TableCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil)
{
cell = [[TableCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(void)configureCell:(TableCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *obj = [fetchedResultsController objectAtIndexPath:indexPath];
// cell.lblName.text = #"";
[cell.lblName setText:[obj valueForKey:#"first"]];
// cell.lblCity.text = #"";
[cell.lblCity setText:[obj valueForKey:#"city"]];
}
Your fetched results controller is configured to return Person objects, so you need to reference the properties of the relationship indirectly:
[cell.lblCity setText:[obj valueForKeyPath:#"address.city"]];
or if you have created a subclass of NSManagedObject, say as Person, you can amend your code to:
Person *obj = [fetchedResultsController objectAtIndexPath:indexPath];
cell.lblName.text = obj.first;
cell.lblCity.text = obj.address.city;
I'm trying to make my own version of this tutorial here (UICollectionView inside UITableViewCell): http://ashfurrow.com/blog/putting-a-uicollectionview-in-a-uitableviewcell
I'm having difficulties getting the correct count of UICollectionViewCells in each UITableViewCell:
The first cell is correct, it should have two UICollectionViewCells inside the UICollectionView (which of course, is inside a UITableViewCell). The second is what is throwing me up. Every time I make a new save in Core Data, it will add it to the previous cells. The second cell should have one UICollectionViewCell, not two UICollectionViewCells.
Here's my code (the code for AFTableViewCell & AFIndexedCollectionView can be found on the above tutorial link):
The numberOfItemsInSection: for the UICollectionView embedded in the UITableViewCell:
- (NSInteger)collectionView:(AFIndexedCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
NSIndexPath *indexPath;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Group" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSSortDescriptor *urlDescriptor = [[NSSortDescriptor alloc] initWithKey:#"url" ascending:NO];
NSArray *sortDescriptors = nil;
sortDescriptors = [[NSArray alloc] initWithObjects:urlDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSError *error = nil;
NSArray *fetchedObjects = [[managedObjectContext executeFetchRequest:fetchRequest error:&error]objectAtIndex:indexPath.section];
NSString *temp = [fetchedObjects description];
NSArray *tempArg = [temp componentsSeparatedByString:#","];
return [tempArg count];
}
The numberOfSectionsInTableView: for the main UITableView:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
id <NSFetchedResultsSectionInfo> sectionInfo = nil;
NSIndexPath *section;
sectionInfo = [[fetchedResultsController sections] objectAtIndex:section.section];
return [sectionInfo numberOfObjects];
}
The NSFetchedResultsController:
- (NSFetchedResultsController *)fetchedResultsController
{
TBAppDelegate *delegate = (TBAppDelegate *)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = delegate.managedObjectContext;
NSFetchRequest *fetchRequest = nil;
fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = nil;
entity = [NSEntityDescription entityForName:#"Group" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:INFINITY];
NSSortDescriptor *urlDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:NO];
NSArray *sortDescriptors = nil;
sortDescriptors = [[NSArray alloc] initWithObjects:urlDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *frc = nil;
frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[self managedObjectContext] sectionNameKeyPath:nil cacheName:#"Root"];
[frc setDelegate:self];
[self setFetchedResultsController:frc];
return frc;
}
The UITableView cellForRowAtIndexpath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
AFTableViewCell *cell = (AFTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[AFTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
return cell;
}
Thanks in advance.
Use
NSArray *fetchedObjects = [[managedObjectContext executeFetchRequest:fetchRequest error:&error]objectAtIndex:section];
instead of
NSArray *fetchedObjects = [[managedObjectContext executeFetchRequest:fetchRequest error:&error]objectAtIndex:indexPath.section];
in your - (NSInteger)collectionView:(AFIndexedCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section function on line 10
It seems the IndexPath local variable is not initialized in this function. You can get section from the parameter passed.
and you haven't initialized section local variable in your
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
function.
If you do not initialize this variables and use them, they return a garbage value or crashes the program. be careful in these kind of access.
I am using NSFetchedResultsController to fetch data from Core Data and to show them in UITableView. My NSFetchedResultsController looks like this:
- (NSFetchedResultsController *) fetchedResultsController
{
if (_fetchedResultsController != nil)
{
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"PlanPreparation"
inManagedObjectContext:_context];
[fetchRequest setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"plan_id == %#", _planCycleID];
[fetchRequest setPredicate:pred];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
fetchRequest.sortDescriptors = sortDescriptors;
_fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;
// but if there is no results I am making another fetch by another type of NSManagedObject
if (_fetchedResultsController.fetchedObjects.count == 0)
{
NSFetchRequest *fetchRequest1 = [[NSFetchRequest alloc] init];
NSEntityDescription *entity1 = [NSEntityDescription entityForName:#"Preparation"
inManagedObjectContext:_context];
[fetchRequest1 setEntity:entity1];
NSPredicate *pred = [NSPredicate predicateWithFormat:#"ismer == %#", [NSNumber numberWithInt:1]];
[fetchRequest1 setPredicate:pred];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
fetchRequest1.sortDescriptors = sortDescriptors;
_fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest1 managedObjectContext:_context sectionNameKeyPath:nil cacheName:nil];
_fetchedResultsController.delegate = self;
//return _fetchedResultsController;
}
return _fetchedResultsController;
}
If I am not retreiving something after first attempt to fetch, I need to set another fetch. In -cellForRowAtIndexPath I need to show data depends on type of NSManagedObjectObject:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if ([[self.fetchedResultsController objectAtIndexPath:indexPath] isKindOfClass:[PlanPreparation2 class]])
{
PlanPreparation2 *planDrug = (PlanPreparation2 *)[self.fetchedResultsController objectAtIndexPath:indexPath];
CDPreparation *prep = (CDPreparation *)[[PTDataManager sharedManager]getDrugByID:planDrug.guid];
cell.textLabel.text = [NSString stringWithFormat:#"%#", prep.name];
}
else
{
CDPreparation *drug = (CDPreparation *)[self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [NSString stringWithFormat:#"%#", drug.name];
}
return cell;
}
but logging shows that -isKindOfClass: don't work here, I am not getting into quotes at all.
Question:
How can I find out type of NSManagedObjectObject?
as shown in the picture change the name and class in data model inspector of that entity
name and class field in data model inspector must be same as name of entity table.
and then after you can compare like
if([(NSManagedObject *)[self.fetchedResultsController objectAtIndexPath:indexPath] isKindOfClass:[Category class]])
as "category" is the class in my case you can choose your own as you write above [PlanPreparation2 class]
if still you face problem then comment below
I have built some code from a tutorial I found in a book. It works and I am able to display my data from CoreData successfully in a tableView. I now want to identify the data/object that the fetchRequest returns. I feel like such a dummy because I cannot understand the syntax enough to isolate my object containing my array of data. This is a snippet of the code which I am having difficulty understanding:
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Sessions" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];
//NSLog(#"Entity is set to: %#", entity);
NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:#"refid" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
//[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:_context sectionNameKeyPath:nil cacheName:#"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Sessions *info = [_fetchedResultsController objectAtIndexPath:indexPath];
//Format cell data ready to be displayed
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"EE, dd LLL yyyy"];
NSString *dateString = [dateFormat stringFromDate:info.date];
NSNumber *dist1Nbr = info.dist1;
int dist1Int = [dist1Nbr integerValue];
float distIntKorM = ([dist1Nbr integerValue])/1000;
NSString *dist1StrMeters = [[NSString alloc] initWithFormat:#"%i", dist1Int];
NSString *dist1StrKorM = [[NSString alloc] initWithFormat:#"%.01f", distIntKorM];
//Select image to display
if ([info.sport isEqualToString:#"Run"]) {
UIImage *image = [UIImage imageNamed:#"trainers-15x10.png"];
cell.imageView.image = image;
cell.textLabel.text = [[NSString alloc] initWithFormat:#"%#: (%#),", dateString, info.sport];
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:#"Type: %#, Dist: %#", info.sessiontype, dist1StrKorM];
} else if ([info.sport isEqualToString:#"Other"]) {
UIImage *image = [UIImage imageNamed:#"weights-15x10.png"];
cell.imageView.image = image;
cell.textLabel.text = [[NSString alloc] initWithFormat:#"%#: (%#),", dateString, info.sport];
cell.detailTextLabel.text = [[NSString alloc] initWithFormat:#"Type: %#, Dist: %#", info.sessiontype, dist1StrKorM];
}
}
If anyone can help me it would be massively appreciated.
You can access an array of NSFetchedResultsSectionInfo objects by calling:
NSArray *sections = _fetchedResultsController.sections;
Each of these objects represents a section in your table. For a given section, you can do something like:
id<NSFetchedResultsSectionInfo>section = sections[0];
NSArray *objects = section.objects;
to access the managed objects in that section. Or, if you've got an index path, you can access the associated object directly by doing:
NSManagedObject *object = [_fetchedResultsController objectAtIndexPath:indexPath];
On in reverse:
NSIndexPath *indexPath = [_fetchedResultsController indexPathForObject:object];
Is this what you're looking for?
update
Forgot this one. As Juan suggested below, you can access all fetched objects with:
NSArray *allObjects = _fetchedResultsController.fetchedObjects;
From the code you posted the NSFetchedresultsController is going to return all objects of class Sessions ordered descending by key 'refid'. NSFetchedResultsCOntroller is used together with a UITableViewController to display the results of a fetch request to the Core Data storage.
However if you want just to obtain all the objects in a array without using the table view you could do the following, for example in viewWillAppear:
if (self.managedObjectContext) {
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Sessions"];
request.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"refid" ascending:NO];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];
[self.fetchedResultsController performfetch];
NSArray *results = [self.fetchedResultsController fetchedObjects]; // an array of Sessions objects ordered descending by refid key
for (Sessions *sessions in results) {
NSLog(#"Sessions = %#", sessions);
}
}
You have to make sure that the NSManagedContext is properly initialized before or nothing will be displayed.
I have two different views, controlled by two different view controllers. Each view has a UITableView inside it. Each UITableView is hooked to a NSFetchedResultsController. In View 1, I do not want to narrow my FRC results, so I do not use a predicate. In View 2, I use a predicate to get certain objects based on a BOOL (aka NSNumber!) value. But when I try to use this predicate, I get an NSRangeException (index 1 beyond bounds) when I segue to View 2. It also throws that exception when I switch the predicates (predicate on View 1, no predicate on View 2). And again the exception comes when I segue to View 2. There are cases where it is successful (neither of which is what I want):
1) I do not use any predicate for either fetch request.
2) I use the same predicate for the fetch request for both View 1 and View 2.
Some code for your enjoyment:
In View1.m:
-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSManagedObjectContext *context = [CoreDataHelper getContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"EditableSong" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"dateModified" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
[fetchRequest setFetchBatchSize:5];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context sectionNameKeyPath:nil
cacheName:#"Root"];
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
In View2.m
-(NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSManagedObjectContext *context = [CoreDataHelper getContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"EditableSong" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sort = [[NSSortDescriptor alloc]
initWithKey:#"dateModified" ascending:NO];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];
NSPredicate *myPredicate = [NSPredicate predicateWithFormat:#"collaborative == %#", [NSNumber numberWithInt:0]];
[fetchRequest setPredicate:myPredicate];
[fetchRequest setFetchBatchSize:5];
NSFetchedResultsController *theFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context sectionNameKeyPath:nil
cacheName:#"Root"];
NSLog(#"here");
self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
And this is where the green error arrow (SIGABRT) points to (this code is the same in View1 and View2 by the way):
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *MyIdentifier = [NSString stringWithFormat:#"MyIdentifier %i", indexPath.row];
SongTableViewCell *cell = (SongTableViewCell *)[tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
EditableSong *song = [_fetchedResultsController objectAtIndexPath:indexPath];//<<<------HERE!!! SIGABRT
song.audioPlayer = [[AudioPlayer alloc] initWithSong:song];
cell = [[SongTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier editableSong:song andVC:self];
UIButton *playButton = [UIButton buttonWithType:UIButtonTypeCustom];
[playButton setBackgroundColor:[UIColor clearColor]];
[playButton setImage:[UIImage imageNamed:#"mainmenuplay.png"] forState:UIControlStateNormal];
playButton.frame = CGRectMake(300.0f, 15.0f, 65.0f, 65.0f);
[playButton addTarget:self action:#selector(playSong:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:playButton];
}
return cell;
}
Thanks!
Update 1
Here is my numberOfRowsInSection method (again, same for both classes):
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
id sectionInfo =
[[_fetchedResultsController sections] objectAtIndex:section];
NSLog(#"%i", [sectionInfo numberOfObjects]);
return [sectionInfo numberOfObjects];
}
For reference, that log is supposed to print 3 in View1 and 1 in View2, but it prints 3 in both.
It seems you are returning the wrong number of cells. cellForRowAtIndexPath: wants to create a cell, but there is no objectAtIndexPath.
So you will need to check your numberOfRowsInSection method.
Problem solved:
Had to change the cache to nil.
See this post:
http://iphoneincubator.com/blog/data-management/delete-the-nsfetchedresultscontroller-cache-before-changing-the-nspredicate