Zach
Zach

Reputation: 4069

How to fetch core data on background thread, read results on main thread synchronously?

If I have 100,000 entities in a core data store, how could I get access to/load/fetch all 100,000 in a background thread, and once loaded/fetched access the properties of these entities on the main thread/other threads? (For example, showing the items in a UICollectionView) I will be using batching to avoid loading all 100,000 into memory - but I will need to know exactly how many there are after the initial load.

Something like this:

// The load occurs on a background thread
[self loadCoreData: ^{
    // Once loaded, dispatch back onto the main thread to get the number of
    // entities, or I could do something like [self getEntityMatchingProperties:...]
    // etc. the point being it accesses entity information that has been loaded but
    // on a different thread.
    dispatch_async(dispatch_get_main_queue(), ^{
        self.title = [self getNumberOfCoreDataEntities];
    });
}];

Edit: another (more exact example):

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // The load occurs on a background thread
    [self loadCoreData: ^{
        [self.collectionView reloadData];
    }];
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    return [self numberOfItemsLoadedFromCoreData];
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    ...
    Entity *entity = [self getItemLoadedFromCoreDataAtIndexPath:indexPath];
    ...
}

In the second example I'm trying to use a NSFetchedResultsController I suppose - are there any full examples of this type of approach? All of them I see deal with snippets doing the fetch with the main context - which would do the work on the main thread.

Upvotes: 0

Views: 788

Answers (1)

Tom Harrington
Tom Harrington

Reputation: 70946

You seem to be reinventing NSFetchedResultsController, which will handle everything you need here. You're making things unnecessarily hard for yourself. This is a common need, and Apple's got you covered. Create the NSFetchedResultsController with your fetch request, and implement your collection view methods to ask it for objects based on index path. As a bonus, NSFetchedResultsController delegate methods can be used to update your collection view if the underlying data changes.

Upvotes: 1

Related Questions