调用dequeueReusableCellWithIdentifier:在heightForRowAtIndexPath中调用cellId

时间:2014-05-10 02:28:15

标签: ios uitableview

我正在开发ios应用程序,

我有一个普通的表视图。当调用heightForRowAtIndexPath时,我正在进行下面的

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellId = [self getCellIds][indexPath.row];
    BaseTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

    return [cell calculateHeigh];
}

基本上我将单元格出列,因为我在每个将进行高度计算的单元格中都有一个函数calculateHeigh。这是正常的工作,但我有一个问题:

dequeueReusableCellWithIdentifier:内拨打heightForRowAtIndexPath是否安全?会引起任何问题吗?

修改

为了澄清我为什么这样做,我有大量需要加载不同标识符的自定义单元格。并且为了避免在我的heightForRowAtIndexPath中有一个巨大的if-else语句,我将单元格高度的吸气剂放在自定义单元格中,我只是要求它返回它(没有计算在那里),我不能作为一个类方法,因为我不知道哪个类,我可以从标识符而不是类中获取对象。而且我想避免一个很大的if-else只是为了代码可读性。

所以我关注的是dequeueReusableCellWithIdentifier:在获得高度时调用它是否很重要?它会导致内存问题还是滞后?或者是否值得做一个错误,如果 - 否则使用字典?

3 个答案:

答案 0 :(得分:1)

首先,您应该避免在表格绘制方法中进行任何计算(例如heightForRow,cellForRow等)。这些方法被称为很多,虽然你的表可能很短和/或不复杂(自定义单元格有很多标签,按钮和图像),你应该总是尝试优化这个绘图过程,否则用户将遇到一些令人讨厌的滞后滚动。

所以你应该在调用之前调用一些方法来准备数据' reloadTable'

-(void)prepareMethod
{
    //get only one cell to calculate all row heights
    BaseTableViewCell *cell = [_myTableView dequeueReusableCellWithIdentifier:cellId];

    for (NSDictionary* dataObj in _dataArray)
    {
        //loop through all rows data and set new property for row height
        dataObj[@"rowHeight"] = [cell calculateHeigh];
    }
}

然后在调用heightForRow时只传递此值而不需要任何昂贵的操作(例如可能是字符串计算):

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //always make sure you don't access unexisting array index
    return ( indexPath.row < _dataArray.count ) ? _dataArray[indexPath.row][indexPath.row][@"rowHeight"] : 1.0;
}

当然,您不需要单独的方法来填充数据数组中的行高 - 您可以在填充(格式化)数据数组时填充此值以避免第二次数组迭代。这一切都取决于您当前的实施情况。

请记住,昂贵的绘图方法(不仅适用于表格)应始终尽可能短,只需获取绘图和绘图所需的数据。这真的很简单。如果您需要进行一些复杂的计算,请在此之前(可能在视图init中)进行,以便在实际绘制之前准备好数据。这样,即使使用更大的表,您的应用程序也可以顺利运行(因为无论表有多大,UITableViewController都只绘制可见单元格。)

此致

hris.to

答案 1 :(得分:0)

您不应使用此方法来提供计算。根据我在您的设置中看到的内容,您将根据单元格中已有的值计算高度。会发生的情况是,单元格出列系统会为您提供重用单元格,但由于它是从多个索引路径共享单元格,因此该单元格可能具有属于与当前索引路径不同的索引路径记录的数据。获取计算高度代码并尝试在您正在使用的数据源回调中重现它。

答案 2 :(得分:0)

我不想在heightForRowAtIndexPath中使用大的if语句并使用dequeueReusableCellWithIdentifier访问单元格。你从每个细胞获得细胞高度的方法是合理的。我相信你的calculateHeigh返回值取决于你传入单元格的表格数据。

在BaseTableViewCell.h中

+ (CGFloat)heightWithData:(id)data;

在BaseTableViewCell.m

+ (CGFloat)heightWithData:(id)data
{
    //put your calculateHeigh logic here. I believe your calculateHeigh depends on the data each cell has.
}

然后你可以做

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return [BaseTableViewCell heightWithData:[self.tableData objectAtIndex:indexPath.row]];
}

如果这样做,您不需要访问每个单元格对象以获得单元格高度。