即使我有批量设置,NSFetchedResultsController也会加载所有行 [英] NSFetchedResultsController is loading all rows even through I have batch set

查看:64
本文介绍了即使我有批量设置,NSFetchedResultsController也会加载所有行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

确定。这是完全相同的问题:为什么NSFetchedResultsController在设置获取批量大小时加载所有行?

Ok. This is the exact same question as here: Why is NSFetchedResultsController loading all rows when setting a fetch batch size?

但是他的解决方案并没有解决我的问题。

But the solution for his doesn't solve for mine.

我有一个有几千条记录的屏幕,加载速度很慢。我将批量大小设置为30(大约是屏幕上单元格的三倍),它仍然循环并加载所有批次由于某种原因。

I have a screen that has several thousand records and is slow to load them all. I set the batch size to 30 (roughly three times the cells on the screen) and it still loops through and loads all the batches for some reason.

这是代码

- (NSFetchedResultsController *)guestCardFetchedResultsController
{
    if (guestCardFetchedResultsController != nil) {
        return guestCardFetchedResultsController;
    }

    // SELECT * from GuestCard
    NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"GuestCard" inManagedObjectContext:self.context];
    [fetchRequest setEntity:entity];
    // ORDER BY updated DESC
    NSSortDescriptor* updatedSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"created" ascending:NO];
    [fetchRequest setSortDescriptors:@[updatedSortDescriptor]];
    fetchRequest.fetchBatchSize = 30;
    NSString *cacheName = self.isReportProblemView ? @"reportProblemGuestCardsAll" : @"guestCardsAll";

    [NSFetchedResultsController deleteCacheWithName:cacheName];
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:@"sectionIdentifier" cacheName:cacheName];
    aFetchedResultsController.delegate = self;
    self.guestCardFetchedResultsController = aFetchedResultsController;

    // Clean up

    NSError *error = nil;
    if (![[self guestCardFetchedResultsController] performFetch:&error]) {
    }

    return self.guestCardFetchedResultsController;
}

在这种情况下,我没有做任何非常有趣的事情。这里是一些委托代码(不包括单元格创建,我只确认了屏幕上的单元格数量):

I'm not doing anything terribly interesting in this scenario. Here's some of the delegate code (excluding the cell creating, which I confirmed only is called for the number of cells on screen):

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    if ([self.guestCardFetchedResultsController.fetchedObjects count] == 0) {
        return 1;
    }
    // Return the number of sections.
    return [[self.guestCardFetchedResultsController sections] count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if ([self.guestCardFetchedResultsController.fetchedObjects count] == 0) {
        return 1;
    }
    // Return the number of rows in the section.
    id <NSFetchedResultsSectionInfo> sectionInfo = [guestCardFetchedResultsController sections][section];
    return [sectionInfo numberOfObjects];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if ([self.guestCardFetchedResultsController.fetchedObjects count] == 0) {
        return @"";
    }

    return [[self.guestCardFetchedResultsController sections][section] name];
}


推荐答案

阅读上的rel =noreferrer> docs,我认为问题是你在获取请求(已创建)中有一个排序,它不会自然地与节键路径(sectionIdentifier)排序相同。我正在查看的文档中的特定句子说:

After reading the docs on the NSFetchedResultsController initializer, I think the problem is that you have a sort in the fetch request (created) that doesn't naturally sort the same as the section key path (sectionIdentifier). The specific sentence in the docs I'm looking at says:


如果此键路径与第一个排序指定的路径不同fetchRequest中的
描述符,它们必须生成相同的相对
顺序

If this key path is not the same as that specified by the first sort descriptor in fetchRequest, they must generate the same relative orderings

我建议修改您的获取请求以进行排序首先在sectionIdentifier上创建。我认为这将解决你的问题。

I recommend modifying your fetch request to sort on sectionIdentifier first, then created. I think that'll fix your issue.

 NSSortDescriptor* updatedSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"created" ascending:NO];
 NSSortDescriptor* sectionSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"sectionIdentifier" ascending:NO];
 // It's critical the sectionSortDescriptor is first
 [fetchRequest setSortDescriptors:@[sectionSortDescriptor, updatedSortDescriptor]];

请注意,如果创建了 sectionIdentifier 属性实际上是实体类的方法,这肯定会强制Core Data在排序/分区之前加载所有数据,因为它需要在每个实体上执行该方法首先。

Note that if either the created or sectionIdentifier properties are actually methods on your entity class, that will definitely force Core Data to load all your data before it can sort/section, because it needs to execute that method on each entity first.

这篇关于即使我有批量设置,NSFetchedResultsController也会加载所有行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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