我正在使用NSFetchedResultsController标准的方式来更新一个UITableView只要有关的核心数据实体发生变化。我所做的和in the Apple documentation一样。NSFetchedResultsController委托分配太多的UITableViewCells
我遇到的问题是当我对新的核心数据实体进行批量插入时。这导致NSFetchedResultsController委托为每个实体分配(并插入)一个新的单元格,但是它没有循环使用UITableViewCells(即总是返回空值)。这意味着分配潜在的100个UITableViewCells,这可能会导致内存问题。有谁知道修补程序或解决方法?谢谢。
编辑1:
在我的UITableViewController子类我有标准NSFetchedResultsControllerDelegate方法。我相信这与Apple的例子是一样的。
-(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationTop];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
// Reloading the section inserts a new row and ensures that titles are updated appropriately.
[tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationTop];
break;
}
}
-(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationTop];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationBottom];
break;
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}
也是我的UITableViewController子类中我有获取细胞对于给定indexPath如下:
-(void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Waypoint *waypoint = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [waypoint comment];
}
-(UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"WaypointCell"; // matches identifier in XIB
UITableViewCell *cell = [aTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSLog(@"new cell");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
} else {
NSLog(@"recycled cell");
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
在tableView:cellForRowAtIndexPath:
功能我添加的NSLog语句来显示这是怎么回事。
这是发生了什么事。上面提到的UITableViewController被推入导航堆栈。异步请求消失并获取一堆数据,并创建或修改与此fetchController相关的数据。一旦调用[self.tableView endUpdates]
,系统开始创建UITableViewCells并将其插入到UITableView中。在调试器控制台中,输出“新单元”被多次打印(可以在100年代编号),我相信这是每个创建的新实体的一个。只有在tableview被加载后(如果它没有因内存问题而崩溃)并且我开始滚动时,我是否可以在控制台中看到“回收单元”输出。
我只注意到你一共有4个问题,他们都没有一个公认的答案。如果答案解决了您的问题,您应该通过点击绿色标志来接受答案。 :) – Florin 2010-08-16 14:09:34
你需要显示你的代码。这不是正常的行为。代表本身不会创建单元格。您不正确地插入某处的单元格。 – TechZen 2010-08-17 00:48:01
弗洛林:我会适当地重新访问和更新。感谢提高。 TechZen:我已经在原文中添加了一些代码。我希望能够对这个问题有所了解。最初我使用了一个自定义tableviewcell与.xib,但我简化了代码使用标准的UITableViewCell和行为是完全一样的。更正委托不创建单元格。这是来自委托的[tableView endUpdates]调用。谢谢。 – chris 2010-08-17 10:16:06