我应该使用dequeReusableCellWithIdentifier吗?

时间:2016-08-29 07:21:49

标签: ios swift uitableview

我知道这个问题很愚蠢。但是我突然想到了这个问题。

当我使用 dequeReusableCellWithIdentifier 时,将重复使用这些单元格。更具体地说,首先'n'组的单元格被重用 - 以及它们的引用

由于重用了相同的引用,我实际上无法将局部变量存储到单元格中。我实际上需要每次在cellForRowAtIndexPath

中分配它们

假设我正在使用自定义复杂的UITableviewcell。 (我知道我们应该减少复杂性。但仍然......)

有些观点将被添加到单元格中。

我能想到的最佳例子是图像滑块。

因此,图像滑块中的图像数量因数据源而异。所以我需要在cellForRowAtIndexPath中添加视图。无法避免。

由于重用了相同的单元格引用,我需要在每次调用cellForRowAtIndexPath时添加这些视图。我认为这有点沉重负担。

我想过使用 drawRect 方法,但它不适用于 UITableViewAutomaticDimension

如果我不使用dequeReusableCell,我会有单独引用的单元格,但会耗费内存和性能。

那么什么是最好的解决方案? 我可以使用dequeReusableCell并且仍然不需要重写其内容吗?

编辑1: 通过提到dequeReusableCell,我确实提到了dequeueReusableCellWithIdentifier - forIndexPath。对不起,我很抱歉。

编辑2: 我觉得,我的问题并不是那么清楚。

让我们考虑一下我的viewcontroller中有一个数组。 我在cellForRowAtIndexPath中使用dequeueReusableCellWithIdentifier配置我的单元格 - forIndexPath

所以当我滚动时,当不可见的行变得可见时,会调用cellForRowAtIndexPath。

让我说我有一个带有n个图像视图的图像滑块。对于每个单元格,这个'n'不同。所以我不得不根据dataSource绘制单元格的视图。

因此每次tableView调用cellForRowAtIndexPath时,都会反复配置单元格。

我希望避免这种情况以提高效果。

5 个答案:

答案 0 :(得分:1)

我在这种情况下的做法如下:

  1. 我总是使用dequeReusableCell:,原因是你已经说过了
  2. 我在自定义cleanCell类中编写了一个UITableViewCell方法,以便清除已在单元格上设置的所有内容(只是为了让它可以重复使用)
  3. 然后在cellForRowAtIndexPath:我根据需要配置我的单元格

答案 1 :(得分:1)

这就是我要做的事情:我会提出在细胞类本身中加入那些沉重观点的逻辑。因此,在cellForRowAtIndexPath中我只需要设置一个必须在单元格内显示的对象,单元格将自己创建所有必要的视图(毕竟它是一个视图层)。所以在cellForRowAtIndexPath里面看起来像这样:

cell = [tableView dequeueReusableCellWithIdentifier...forIndexPath...];
cell.modelObject = myModelObject;

那就是它。

然后在单元格类中,我将实现在不同模型对象之间切换的优化。就像,当重复使用单元格时,您可以推迟释放重视图并重用它们。

说实话,我没有用滑块获得你的例子,但是假设你有5颗星的星级评分,可以看到或不可见。有多种方法可以做到这一点,但我们假设您只为每个星添加/删除UIImageView。您现在的方式是,您将拥有一个空单元格,并在cellForRow中创建/添加视图。我建议的是将5 UIImageView作为您单元格的一部分,并在单元格中根据modelObject.rating设置其可见性。这样的事情。我希望,这有助于说明我的观点:)

UPDATE :当您的单元格内部有任意数量的图像时,我可能会在单元格的类中创建它们。因此,例如,对于第一个模型对象,我们需要3个图像视图。所以我们创造它们。但是我们不会在prepareForReuse中释放它们,我们等待下一个模型对象的到来。如果它有1个图像,我们会发布2个图像视图(或者我们不会,所以我们以后不必重新创建它们,这取决于什么更重要:性能或内存用法),如果它需要5,我们再创建两个。如果它需要3,我们已经完成了所有设置。

答案 2 :(得分:0)

在您的情况下,您应该使用dequeueReusableCellWithIdentifier(_ identifier: String, forIndexPath indexPath: NSIndexPath)方法。此方法自动决定是否需要创建或出列单元格。

  

我需要在每次调用cellForRowAtIndexPath时添加这些视图。我认为这有点沉重负担。

每次调用cellForRowAtIndexPath时,您都不需要添加这些视图。应该在实例化单元格时添加这些视图。在cellForRowAtIndexPath中,您只能为这些视图指定图片和其他值。

如果您使用故事板和原型单元格,您的代码应如下所示:

var items = [UIImage]()

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("ImageCell", forIndexPath: indexPath)

    let item = items[indexPath.row]
    let recipient = item.recipients.first

    // I have given my UIImageView tag = 101 to easily access it from the view controller.
    // This allows me to avoid defining a custom UITableViewCell subclass for simple cells.
    if let imageView = cell.viewWithTag(101) as? UIImageView {
        imageView.image = item
    }

    return cell
}

答案 3 :(得分:0)

1)我认为你需要使用" lazy load"细胞 http://www.theappguruz.com/blog/ios-lazy-loading-images(例如)

2)您可以在viewController中创建一个属性,并创建一个NSMutableDictionary属性,该属性将通过某个键存储一些数据, 如果你的模特有像" ID"单元格或者你可以使用indexPath.row,然后你只能加载一次,下次调用-cellForRow时,你可以通过

从字典中检索数据。

[self.dataDictionary objectForKey:@" cellID"];

有了这个你,解决你的重复负荷。 在-cellForRow中,您可以设置检查,例如。

if ([self.dataDictionary objectForKey:@"cellID"]) {
  cell.cellImage = [self.dataDictionary objectForKey:@"cellID"];
} else {
  UIImage *img = [uiimage load_image];
  cell.cellImage = img;
  [self.dataDictionary setObject:img forKey:@"cellID"];
}

等等。例如,您可以自己选择dataType,这是一个例子。

答案 4 :(得分:0)

感谢大家帮帮我。我认为更好的答案来自@Eiko。

使用可重复使用的单元时,必须完全可重复使用。如果要根据数据更改其视图,则必须使用新标识符或避免使用可重用单元格。

但是,避免可重复使用的细胞,将需要负担。因此,您应该为类似的单元格使用不同的标识符,或者@FreeNickName告诉您 - 您可以使用中间配置并根据需要对其进行更改。