来自 Core Data 请求的分页结果 [英] Paging results from Core Data requests

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

问题描述

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

<代码>NSFetchRequest* request = [[[NSFetchRequest alloc] init] autorelease];[请求 setEntity:[...]];[请求 setPredicate:[NSPredicate predicateWithFormat:@"flaggedTime != nil"]];NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"flaggedTime" 升序:NO];[请求 setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];[请求 setFetchLimit:pageSize];[请求 setFetchOffset:((pageIndex - 1) * pageSize)];NSArray* results = [self.context executeFetchRequest:request error:NULL];

pageSize 为 30,测试数据的 pageIndex 为 1、2、3 或 4(DB 中大约有 80 个项目,因此 pageIndex = 4 不应返回任何项目).谓词和排序工作正常,结果成功返回.获取限制也可以正常工作.不会返回任何错误.

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

有人知道为什么吗?我会非常感谢您的每一个回答.

更新:我说的是 iOS.在 4.2 和 5.0 上测试.

更新 2:简化问题.

<代码>NSFetchRequest* request = [[[NSFetchRequest alloc] init] autorelease];[请求 setEntity:[...];NSError* 错误 = 零;NSManagedObjectContext* context = [...];NSUInteger count = [context countForFetchRequest:请求错误:&error];断言(错误 == 零);NSLog(@"总计数:%u", count);request.fetchOffset = 0;request.fetchLimit = 30;NSLog(@"获取偏移量: %u, limit: %u", request.fetchOffset, request.fetchLimit);NSArray* page1 = [context executeFetchRequest:request error:&error];断言(错误 == 零);NSLog(@"第 1 页计数:%u", page1.count);request.fetchOffset = 30;request.fetchLimit = 30;NSLog(@"获取偏移量: %u, limit: %u", request.fetchOffset, request.fetchLimit);NSArray* page2 = [context executeFetchRequest:request error:&error];断言(错误 == 零);NSLog(@"第 2 页计数:%u", page2.count);

给出:

<前>总数:34获取偏移量:0,限制:30第 1 页计数:30获取偏移量:30,限制:30第 2 页计数:30(错误:应该给出 4)

解决方案

NSFetchRequestpageOffset 属性(有时?)在您针对未保存的文件运行提取请求时被忽略语境.请注意在代码中 OP 上下文是如何永远不会保存的,而在@kcharwood 的答案所附的代码片段中,它实际上被保存了.下面是一个例子:

- (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(@"获取的对象: %@ 
count: %d", s, array.count);}/* 示例本身 */NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];[上下文设置PersistentStoreCoordinator: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" 升序:YES]];request.fetchLimit = 30;NSArray * result = [context executeFetchRequest:request error:nil];[self printArrayOfTestEntities:result];request.fetchOffset = 30;结果 = [上下文executeFetchRequest:请求错误:nil];[self printArrayOfTestEntities:result];[上下文保存:&错误];request.fetchOffset = 0;结果 = [上下文executeFetchRequest:请求错误:nil];[self printArrayOfTestEntities:result];request.fetchOffset = 30;结果 = [上下文executeFetchRequest:请求错误:nil];[self printArrayOfTestEntities:result];

日志:

2014-03-01 11:30:06.986 coredatatest[19771:70b] 获取对象:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 204 23 125 26 27 28 29数:302014-03-01 11:30:06.990 coredatatest[19771:70b] 获取的对象:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 2 2 2 2 2 2 2 9数:302014-03-01 11:30:06.995 coredatatest[19771:70b] 获取的对象:0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 26 22 20 29数:302014-03-01 11:30:06.997 coredatatest[19771:70b] 获取的对象:30 31 32 33数:4

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 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.

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.

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

Update 2: To simplify the problem.


    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);

gives:

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)

解决方案

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: %@ 
count: %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];

The log:

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天全站免登陆