Take the 2-minute tour ×

Data Model

I'm building an interface to allow users to filter a set of Photos. The data model is above. I'd like the disable any controls that would result in 0 results.

To accomplish this, I'm running new fetch requests for every control that is off/not selected each time the user makes their own change. I add the data that the control represents to my NSCompoungPredicate, then remove it after I get the result. If the count of the result is 0, I disable that control.

I'm doing this all on the main thread so in some cases there is a bit of a lag in the app. Is there a better way to do this type of filtering with less overhead? Should I run these filter fetches on their own thread? I've never done that with CoreData and worm what I've read I need a separate context for that and I'm not sure how to go about setting up code for that.

share|improve this question
add comment

1 Answer

up vote 1 down vote accepted

A bit of code would help. Aside from that, here are a few suggestions.

First, on your fetch request, use countForFetchRequest:error: because it will just query the database, and return the count instead of object information.

Second, if you don't want to use threads, and the search is still too slow, you can do the initial query when the app starts. This will then enable/disable the various controls.

You can simple catch the context notifications that tell when data has changed, and update that information accordingly. Then, you don't have to do any queries at all. Just initialize, and update the status as objects are added/removed from the database.

If you want to use threads, then that's not really all that difficult.

It sounds like all you want is a thread that is just running queries. You setup a MOC...

NSManagedObjectContext *checkerMoc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
checkerMoc.persistentStoreCoordinator = MyCurrentMoc.persistentStoreCoordinator;

Now, whenever you want to check the database...

[checkerMoc performBlock:^{
    NSFetchRequest *fetchRequest = ...
    // Do your fetch request... this block of code is running in the other thread
    [checkerMoc fetch...];
    // When the fetch request is done, do whatever you want in your UI...
    dispatch_async(dispatch_get_main_queue(), ^{
        // Now this code is running in the main thread... access your UI
        self.myControl.enabled = fetchResultCount > 0;

Note, you are using the same persistent store coordinator, so if the main thread tries to access the database, it will get stacked behind this request. You can also use a separate persistentStoreCoordinator for checkerMoc is this is an issue.

share|improve this answer
Thank so much! Calling countForFetchRequest actually made a noticeable difference –  ChickensDontClap Apr 25 '12 at 18:28
add comment

Your Answer


