我的核心数据数据库中有数千个点,我想将它们全部放在我的tableView中,但我不想一次性将它们提取到内存中,但是我想使用NSFetchedResultsController并用一些常量批量处理它们.我设置它就像我在许多教程中看到的那样,我设置了fetchBatchSize属性,但是在显示之前加载视图控制器花了几秒钟.
- (void)initPositionsFetch { // Initialize Fetch Request NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"OpenPositionCD"]; // Add Sort Descriptors [fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:NO]]]; // Add predicate [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"moduleId == %@",_module.moduleId]]; [fetchRequest setFetchBatchSize:100]; [fetchRequest setIncludesPendingChanges:NO]; // Initialize Fetched Results Controller self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:temporaryContext sectionNameKeyPath:nil cacheName:nil]; // Configure Fetched Results Controller [self.fetchedResultsController setDelegate:self]; // Perform Fetch NSError *error = nil; [self.fetchedResultsController performFetch:&error]; if (error) { NSLog(@"Unable to perform fetch."); NSLog(@"%@,%@",error,error.localizedDescription); } }
NSFetchedResultsControllerDelegate方法:
#pragma mark - NSFetchedResultsControllerDelegate - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller { [self.tableView beginUpdates]; } - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller { [self.tableView endUpdates]; } - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath { switch (type) { case NSFetchedResultsChangeInsert: { [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; } case NSFetchedResultsChangeDelete: { [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; break; } case NSFetchedResultsChangeUpdate: { [self configureCell:(PanelPositionCell *)[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath]; break; } case NSFetchedResultsChangeMove: { [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade]; break; } } }
UITableView委托方法:
#pragma mark - UITableViewDataSource - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { if (_tracksVisible) return 1; else return [[self.fetchedResultsController sections] count]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (_tracksVisible) return [_tracks count]; else { NSArray *sections = [self.fetchedResultsController sections]; id<NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section]; return [sectionInfo numberOfObjects]; } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier; if(_tracksVisible) CellIdentifier = TrackCellIdentifier; else CellIdentifier = PositionCellIdentifier; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; if(_tracksVisible) { [((PanelTrackCell *)cell) setValuesByTrackCD:[_tracks objectAtIndex:indexPath.row]]; } else { [self configureCell:(PanelPositionCell *)cell atIndexPath:indexPath]; } return cell; } - (void)configureCell:(PanelPositionCell *)cell atIndexPath:(NSIndexPath *)indexPath { // Fetch Record NSManagedObject *record = [self.fetchedResultsController objectAtIndexPath:indexPath]; OpenPositionCD *position = (OpenPositionCD *)record; // Update Cell [cell setValuesByOpenPositionCD:position]; }
这有什么问题?为什么要加载所有行?可能是Core Data模型的问题?我试图删除谓词,但它没有帮助.必须设置SortDescriptor,但这只是我想到的问题所在.我希望结果按时间戳排序.时间戳是Date属性,设置为Indexed.首先我必须得到它然后我可以按时间对它们进行排序,如何对结果进行批处理?我使用tableView通过switch(_tracksVisible)显示另一个数据应该不是问题,对吧?
[[[self fetchedResultsController] managedObjectContext] performBlock:^{ NSError *error = nil; [self.fetchedResultsController performFetch:&error]; if (error) { NSLog(@"Unable to perform fetch."); NSLog(@"%@,error.localizedDescription); } [[NSOperationQueue mainQueue] addOperationWithBlock:^{ [_tableView reloadData]; }]; }];
发生了什么事情,控制器显示得更早,但随后UI冻结,几乎与以前相同.
解决方法
在BatchSize中尝试使用较低的值,可能是20
[fetchRequest setFetchBatchSize:20];
您也可以尝试添加initPositionFetch
[fetchRequest setFetchLimit:20];