从Core Data请求中分页结果 [英] Paging results from Core Data requests

查看:158
本文介绍了从Core Data请求中分页结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个相对简单的核心数据sqlite数据库。我试图一次从DB一个页面的结果。

I have a relatively simple core data sqlite database. I am trying to get results from DB one page at a time.


    NSFetchRequest* request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:[...]];

    [request setPredicate:[NSPredicate predicateWithFormat:@"flaggedTime != nil"]];

    NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"flaggedTime" ascending:NO];
    [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];

    [request setFetchLimit:pageSize];
    [request setFetchOffset:((pageIndex - 1) * pageSize)];    

    NSArray* results = [self.context executeFetchRequest:request error:NULL];

pageSize为30,pageIndex对测试数据为1,2,3或4 DB中的项,因此pageIndex = 4应该不返回任何项)。
谓词和排序工作正常,结果成功返回。提取限制也很好。没有返回错误。

pageSize is 30, pageIndex on testing data is 1, 2, 3 or 4 (there are about 80 items in DB, so pageIndex = 4 should return no items). Predicate and sorting works fine, results are successfully returned. Fetch limit works fine, too. No errors are returned.

问题:我总是从第一页获得结果,就好像没有设置fetchOffset。我试图删除谓词和排序,但无济于事。
当我可以使fetchOffset工作的唯一情况是当我使用值在30以下。当然,这是无意义的分页...

Problem: I always get results from the first page, as if fetchOffset was not set. I tried to remove the predicate and the sorting but to no avail. The only situation when I could make fetchOffset work was when I used values under 30. Of course, that is meaningless for paging...

有人知道为什么?我会非常感谢每一个答案。

Does anybody know why? I will be really thankful for every answer.

更新:我说的是iOS。测试于4.2和5.0。

Update: I am speaking about iOS. Tested on 4.2 and 5.0.

更新2:简化问题。


    NSFetchRequest* request = [[[NSFetchRequest alloc] init] autorelease];
    [request setEntity:[...];

    NSError* error = nil;

    NSManagedObjectContext* context = [...];

    NSUInteger count = [context countForFetchRequest:request error:&error];
    assert(error == nil);

    NSLog(@"Total count: %u", count);

    request.fetchOffset = 0;    
    request.fetchLimit = 30;

    NSLog(@"Fetch offset: %u, limit: %u", request.fetchOffset, request.fetchLimit);

    NSArray* page1 = [context executeFetchRequest:request error:&error];
    assert(error == nil);

    NSLog(@"Page 1 count: %u", page1.count);

    request.fetchOffset = 30;    
    request.fetchLimit = 30;

    NSLog(@"Fetch offset: %u, limit: %u", request.fetchOffset, request.fetchLimit);

    NSArray* page2 = [context executeFetchRequest:request error:&error];
    assert(error == nil);

    NSLog(@"Page 2 count: %u", page2.count);

给出:


Total count: 34
Fetch offset: 0, limit: 30
Page 1 count: 30
Fetch offset: 30, limit: 30
Page 2 count: 30 (ERROR: should give 4)


推荐答案

pageOffset 属性 NSFetchRequest 是否(有时?)被忽略时,对未保存的上下文运行fetch请求。注意如何在代码中通过OP上下文从不保存,而在代码片段附加到一个答案通过@kcharwood它实际上保存。这里是一个例子:

The pageOffset property of NSFetchRequest is (sometimes?) ignored when you run fetch requests against an unsaved context. Note how in the code by OP context is never saved, while in the code snippet attached to an answer by @kcharwood it is actually saved. Here is an example:

- (void) printArrayOfTestEntities:(NSArray *)array{
    NSMutableString * s = [NSMutableString new];
    NSArray * numbers = [array valueForKey:@"someField"];
    for (NSNumber * number in numbers){
        [s appendString:[NSString stringWithFormat:@"%d ", [number intValue]]];
    }

    NSLog(@"fetched objects: %@ \rcount: %d", s, array.count);
}

/* example itself */

NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[context setPersistentStoreCoordinator:persistentStoreCoordinator];

for(int i = 0; i < 34;i++){
    NSManagedObject * object = [NSEntityDescription insertNewObjectForEntityForName:@"TestEntity"
                                                      inManagedObjectContext:context];
    [object setValue:@(i) forKey:@"someField"];
}

NSFetchRequest * request = [NSFetchRequest fetchRequestWithEntityName:@"TestEntity"];
request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"someField" ascending:YES]];
request.fetchLimit = 30;

NSArray * result = [context executeFetchRequest:request error:nil];
[self printArrayOfTestEntities:result];

request.fetchOffset = 30;
result = [context executeFetchRequest:request error:nil];
[self printArrayOfTestEntities:result];

[context save:&error];

request.fetchOffset = 0;
result = [context executeFetchRequest:request error:nil];
[self printArrayOfTestEntities:result];

request.fetchOffset = 30;
result = [context executeFetchRequest:request error:nil];
[self printArrayOfTestEntities:result];

日志:

2014-03-01 11:30:06.986 coredatatest[19771:70b] fetched objects: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29  
count: 30
2014-03-01 11:30:06.990 coredatatest[19771:70b] fetched objects: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29  
count: 30
2014-03-01 11:30:06.995 coredatatest[19771:70b] fetched objects: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29  
count: 30
2014-03-01 11:30:06.997 coredatatest[19771:70b] fetched objects: 30 31 32 33   
count: 4

这篇关于从Core Data请求中分页结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆