Beginner iPhone programmer here, so bear with me.
Here's the problem: I have a UITableView. I also have a search controller. When the text in the search bar changes, it calls the reloadData method which adds getDataInBackground to the NSOperationQueue. Once the operation is done, it calls [tableView reloadData] in the main thread. Here's the code:
- (void)reloadData{
if(activityLabel.superview == nil) //show activity label
[self.view addSubview:activityLabel];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(getDataInBackground) object:nil];
[queue cancelAllOperations];
[queue addOperation:operation];
[operation release];
}
- (NSPredicate *)getPredicate{
/* Sets up the appropriate predicate using search term and filters, returns it */
}
- (void)getDataInBackground{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSManagedObjectContext *context = [(FitAmp_LibraryAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ExerciseListInfo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:[self getPredicate]];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
NSMutableDictionary *tempExercises = [[NSMutableDictionary alloc] init];
NSString *firstLetter;
NSMutableArray *exercisesSection;
for (ExerciseListInfo *exercise in fetchedObjects) {
firstLetter = [[exercise.title substringToIndex:1] uppercaseString];
if([[NSScanner scannerWithString:firstLetter] scanInteger:NULL])
firstLetter = @"#";
exercisesSection = [tempExercises objectForKey:firstLetter];
if(exercisesSection == nil){
NSMutableArray *newExerciseArray = [[NSMutableArray alloc] initWithObjects:exercise, nil];
[tempExercises setObject:newExerciseArray forKey:firstLetter];
[newExerciseArray release];
}else{
[exercisesSection addObject:exercise];
}
exercisesSection = nil;
}
NSMutableArray *tempSectionsArray = [[tempExercises allKeys] mutableCopy];
self.exercisesSections = (NSMutableArray *)[tempSectionsArray sortedArrayUsingSelector:@selector(compare:)];
self.exercises = tempExercises;
[tempSectionsArray release];
[tempExercises release];
[self.tableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
if(activityLabel.superview)
[activityLabel performSelectorOnMainThread:@selector(removeFromSuperview) withObject:nil waitUntilDone:YES];
[self performSelectorOnMainThread:@selector(printExercises) withObject:nil waitUntilDone:YES];
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
[pool drain];
}
The problem is that when the table reloads data, it appears to use the [self exercises] and [self exercisesSections] from the last time getDataInBackground ran. The value of the 2 objects are current and correct after every search (I print them out with NSLog) but tableView seems to be using an outdated copy.
What do I do?
EDIT: It seems like if I retain self.exercises and self.exercisesSections after I set them, the problem goes away. But then aren't I leaking memory?