如何在 iOS 应用上同步 UITableView 滚动和 CoraData 获取?

Posted

技术标签:

【中文标题】如何在 iOS 应用上同步 UITableView 滚动和 CoraData 获取?【英文标题】:How to synchronize UITableView scrolling and CoraData fetch on iOS app? 【发布时间】:2014-04-14 07:40:21 【问题描述】:

我想实现以下功能,你能帮帮我吗?

我的应用中有核心数据库。在该数据库中,一个模型CourseEvents 包含超过 150000 条记录,每条记录大约有 12 个字段。

每个记录值对应一个UITableViewCell

但我不想在单个提取请求中提取所有记录。想根据UITableView滚动获取一些N的记录数。

例子:

当表视图加载第一次想要获取 200 条记录时,每当用户滚动 UITableView 时需要获取下一个 200 条记录,例如需要根据 UITableview 的滚动从模型中获取数据。

我怎样才能做到这一点。请帮忙......

【问题讨论】:

到目前为止您尝试过什么?您是否已经查看了NSFetchRequest 的 fetchLimits 和 fetchOffset? 我知道 fetchlimit。但我没有寻找 fetchoffset。但我担心的是在加载 tableview 时它应该首先获取 200(例如),当用户向上滚动并到达 150 个单元格时,需要获取下一个 200(201-400),如果用户再次向下滚动,需要获取前一个 200( 1 - 200)。就像我的 fetch 应该与 UITableView 可见单元格同步。 【参考方案1】:

如果我正确理解您的问题,当您最初加载视图时,您只想获取 200 条记录,而在 tableView Scroll 上您想获取下一个 200 条记录,依此类推。您正在使用核心数据,那么在NSFetchedResultsController 的帮助下获取记录会更容易。只需将setFetchBatchSize 设置为您想要获取的任何记录(20 在您的情况下也应该很好)。网上有很多例子,也有很棒的苹果样品。这是CoreDataBooks 示例的链接。这是伟大的tutorial 关于如何使用 NSFetchedResultsController。最后Core Data Programming guide 为您提供帮助。这是关于如何使用 NSFetchedResultController 的示例代码

- (void)viewDidLoad 
    [super viewDidLoad];

    NSError *error;
    if (![[self fetchedResultsController] performFetch:&error]) 
        // Update to handle the error appropriately.
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    




- (NSFetchedResultsController *)fetchedResultsController 

    if (_fetchedResultsController != nil) 
        return _fetchedResultsController;
    

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
        entityForName:@"FailedBankInfo" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sort = [[NSSortDescriptor alloc]
        initWithKey:@"details.closeDate" ascending:NO];
    [fetchRequest setSortDescriptors:[NSArray arrayWithObject:sort]];

    [fetchRequest setFetchBatchSize:20];

    NSFetchedResultsController *theFetchedResultsController =
        [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:managedObjectContext sectionNameKeyPath:nil
            cacheName:@"Root"];
    self.fetchedResultsController = theFetchedResultsController;
    _fetchedResultsController.delegate = self;

    return _fetchedResultsController;



- (NSInteger)tableView:(UITableView *)tableView
    numberOfRowsInSection:(NSInteger)section 
    id  sectionInfo =
        [[_fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];


- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
    EntityName *entity = [_fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = entity.name; //just example
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@, %@",
        entity.city, entity.state];


- (UITableViewCell *)tableView:(UITableView *)tableView
    cellForRowAtIndexPath:(NSIndexPath *)indexPath 

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell =
        [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Set up the cell...
    [self configureCell:cell atIndexPath:indexPath];

    return cell;

【讨论】:

你能解释一下,在你的代码中,当我的 tableview 滚动时,接下来的 200 条记录将从数据库中获取。 NSFetchedResultsController 将处理获取数据的子集(例如核心数据存储中的 20 个项目),并且当您滚动 tableview 时它将获取更多。您不需要放置任何代码来处理数据的获取,它将由 NSFetchedResultsCntroller 在内部处理。试试示例代码或教程链接。 是的,我明白了。谢谢@suhit。 是的,我的错误是。我有单独的模型类,所以从我的角度来看,我认为我应该在UITableView 发生滚动时调用,但现在我知道了如何使用这段代码实现。非常感谢@suhit。 @Nagarajan 请分享您的代码,您在哪里添加了代码以获取接下来的 200 条记录以及如何?我有同样的问题。提前致谢。【参考方案2】:

这个示例项目帮助我实现了我的解决方案。它也可以帮助你。 https://github.com/lukagabric/LargeDatasetSample

【讨论】:

以上是关于如何在 iOS 应用上同步 UITableView 滚动和 CoraData 获取?的主要内容,如果未能解决你的问题,请参考以下文章

同步更新 UITableView 的模式?

firebaseui-ios FirebaseTableViewDataSource 与 UITableView 同步

更改 UITableview 的显示

iOS:UIImageView随着UITableView.rowHeight的变化而变化,如何避免?

带有输入字段的 UITableView - 如何在进入详细视图并返回时保留值

如何在 ios 中的单元格上显示核心数据?