3

I've got an array of 200 numbers (item ids) and I want to get some data from core data for each item using its item id. I am assuming the only way to do so is to query core data within a loop performing the fetchRequest in each iteration and adding the results to a mutable array. This seems like a memory hog and looping over 200 items may not be the best way of getting that data I need.

The destination for all this data is a table so I'd like to use an NSFetchedResultsController, however, that might be asking too much.

What is the best way to retrieve data from core data when you have several hundred items for which you wish to query?

Illustrative code examples would be most appreciated.

Here is my code:

- (NSFetchedResultsController *)fetchedResultsController {

if (_fetchedResultsController != nil) {
    return _fetchedResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"Shows" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];

NSSortDescriptor *sort = [[NSSortDescriptor alloc] initWithKey:@"downloadCount" ascending:NO];

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"showId IN %@", resultsArray];
[fetchRequest setPredicate:predicate];

[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *theFetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                    managedObjectContext:managedObjectContext 
                                      sectionNameKeyPath:nil 
                                               cacheName:nil];

self.fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;

[sort release];
[fetchRequest release];
[theFetchedResultsController release];

return _fetchedResultsController;    

}

1 Answer 1

5

It would be best to use a predicate. For example:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

// Set the entity for the fetch request.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"EntityName" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"myID IN %@", IDArray];

// Set the predicate for the fetch request.
[fetchRequest setPredicate:predicate];

// Perform the fetch.
NSError *error;
NSArray *array = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
[fetchRequest release];

This is a crude example since I don't know the form of your IDs or what is in the core data, but basically you can search the core data for only the IDs stored in your array and can further implement the predicate to return only certain values if you want. This should at least get you started

Sign up to request clarification or add additional context in comments.

12 Comments

What I was missing is the @"myID IN %@", IDArray However, I'm still having an issue as the fetchRequest is not returning any values even though I know that IDArray has 200 entries. I'll add my code to the question.
By looking at it, I can't say I see anything wrong with what you have. What about the code where you perform the actual performFetch: portion?
The problem is that I'm creating the resultsArray from a request to the server for a JSON string. The table is loading with zero cells and so calling [self.tableView reloadData]; after the fetchRequest is returned still does nothing. I may just make the request in the app delegate and update core-data before the user has a chance to get to this page. - Slev... thank you for your help.
You are certainly more than welcome. I'm glad to see you found where the problem is, as well. If it's any easier than performing the fetch in the app delegate, it's possible you could set up a scheduledTimer event that lets the fetch perform its request. Once the timer reaches its end, it could execute the code to reload the tableView data
I had considered that. I guess I could load the old data by default, make the json request in ViewDidLoad and in requestFinished reload the tableView. As I have it now I'm updating the rest of the app's data using XML and am considering switching all update procedures (of which this is but one) to JSON... but I hate having to update all that code. At least it would be consistent and probably more efficient. If I do move to JSON I could do it in the app delegate with all the rest of the updates and simply update the model once and query core-data when I get to this specific page.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.