UITableViewController在滚动时加载我的所有单元格

时间:2013-06-18 20:22:25

标签: ios uitableview

情况:

我有一个视图控制器,它有一个表视图,从数组中获取数据。由于该数组的数据加载速度很慢,我的元素按需加载(在tableView:cellForRowAtIndexPath :)触发。

问题:

在开始时(即在视图加载之后),它仅加载可见单元格(前6个)。但是,当你尝试滚动时,它会立即加载其他所有人! (在加载中通过断点测试,显然[UITableView _createPreparedCellForGlobalRow:withIndexPath:]为每一行调用)

守则:

PlayerListDataModel.m

@implementation PlayerListDataModel
(...)
-(NSString *)nombre {
    if (!self.loaded) [self load];
    return _nombre;
}
-(void)load {
    NSLog(@"Loading %d", self.sqlId);
    [OMNIGAME loadListCell:self];
    self.loaded = YES;
}
@end

PlayerListViewController.m

@implementation PlayerListViewController

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; }

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.jugadores.count;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* cellId = @"PlayerListCell";
    PlayerListCell* cell = [tableView dequeueReusableCellWithIdentifier:cellId];
    if (!cell) {
        cell = [[PlayerListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }
    PlayerListDataModel* data =[self.jugadores objectAtIndex:indexPath.row];
    cell.dem = data.bestDem;
    cell.nombre = data.nombre;
    cell.apellido = data.apellido;
    cell.escudo = data.escudo;
    cell.equipo = data.equipo;
    cell.age = data.edad;
    cell.bandera = data.bandera;
    cell.price = data.price;
    cell.energia = data.energy;
    cell.valor = data.valor;

    return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
    return tableView.bounds.size.height/7;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return tableView.bounds.size.height/7;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    if (!self.search) {
        self.search = [[PlayerSearchView alloc] init];
        self.search.search.delegate = self;
    }
    return self.search;
}

问题:

这是预期的行为吗? 如果是的话,是否有办法破解它?如果没有,我做错了什么?

3 个答案:

答案 0 :(得分:1)

这是一种意想不到的,实际上是无意的行为。我不知道你的自定义单元格的实现,但我无法想象这可能会导致这种行为。在我看来,你的-tableView实现没有问题:cellForRowAtIndexPath:本身。

我的怀疑是(i)在开始滚动你的tableview边界时以某种方式改变,或者(ii)Mac上安装的某些工具会干扰你的模拟器。所以我的建议如下:

(i)正如Dhruv Goel建议尝试硬编码行的高度。如果tableview的边界应该缩小,这可能会导致一些复杂性(行的高度越低,排队的行就越多)。但我无法想象为什么会发生这种情况的合理原因。

(ii)您是否通过模拟器专门调试您的应用程序?如果是,请查看以下链接:UITableViewCell cellForRowAtIndexPath calling large number of rows when first scrolling。像窗口管理那样的工具可能会干扰模拟器。

最后一点引出了另一个问题。您是否检查过UITableViewController的其他子类(在此特定项目中)是否出现此问题?

答案 1 :(得分:0)

是的,这是预期的行为。实际上,这是UITableView的主要功能之一。它只是在内存中保存当前必须在视图中显示的单元格。因此,当您滚动时,表视图会逐个将旧单元格出列,并将它们与新数据一起重用。因此,在您的情况下,最初可以看到5或6个单元格,并且您需要滚动并需要新单元格,即:

PlayerListCell* cell = [tableView dequeueReusableCellWithIdentifier:cellId];
如果可能,

尝试重新使用单元格,如果没有,则使用以下命令创建新单元格:

if (!cell) {
cell = [[PlayerListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}

围绕这个问题的方法是不要将单元格出列,并且每次都创建(alloc init)一个全新的单元格,但不建议这样做。

答案 2 :(得分:0)

这不是一个错误,它已被记录。

委托方法:

tableView:heightForHeaderInSection:

无论屏幕上是哪个单元格,都会调用tableview中的每个单元格。

正如文件中的讨论所说:

  

讨论

     

该方法允许委托指定具有不同高度的行。如果实现了此方法,则它返回的值将覆盖为给定行的UITableView的rowHeight属性指定的值。

     

使用tableView:heightForRowAtIndexPath:而不是rowHeight属性会对性能产生影响。每次显示表视图时,它会在每个行的委托上调用tableView:heightForRowAtIndexPath:这会导致表视图具有大量行(大约1000或更多)的显着性能问题

相关问题