tracy
tracy

Reputation: 384

Possible issue with fetchLimit and fetchOffset in a Core Data query

I have a very sporadic bug with a Core Data query containing fetchLimit and fetchOffset. Once in a long while (I've seen it happen once, as has another tester), the fetchOffset seems to be ignored. The query looks like this:

NSFetchRequest *fetch = [[NSFetchRequest alloc] initWithEntityName:@"MyEntity"];
NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:dateDescriptor];
[fetch setSortDescriptors:sortDescriptors];

fetch.fetchOffset = 500;
fetch.fetchLimit = 1;

NSError *error = nil;
NSArray *objects = [self.managedObjectContext executeFetchRequest:fetch error:&error];
if (objects.count) {
    MyEntity *objectAtLimit = [objects objectAtIndex:0];
}

This almost always returns the 501st object as desired, but on those two occasions where it broke it returned the first object.

The query is never run unless there are >500 rows in the database. I'm using iOS5. The managedObjectContext has a mainQueueConcurrencyType.

It seems to be the same behavior as reported in this question: Paging results from Core Data requests, which was never resolved (or at least not on list.) In that case the fetchOffset appeared to be either ignored or respected based on the data model being tested against.

I'm probably going to rewrite the query without the fetchOffset, just in case that is the problem, since the performance shouldn't be an issue. But I'm wondering if anyone has thoughts about where the bug might be here.

Upvotes: 11

Views: 2861

Answers (2)

SteffenK
SteffenK

Reputation: 712

The problem indeed seems the be connected with unsaved changes in the NSManagedObjectContext. If you set the includesPendingChanges property to false the NSFetchRequest with limit + offset will work as expected.

fetchRequest.includesPendingChanges = false

Upvotes: 0

Casey Fleser
Casey Fleser

Reputation: 5787

Ran across a similar problem this morning and noticed if my NSManagedObjectContext has unsaved changes that the fetchOffset may be ignored for whatever reason. After saving the context the fetchOffset is interpreted correctly.

Upvotes: 16

Related Questions