UITableViewCell - 理解“可重用”

时间:2013-05-02 03:49:34

标签: iphone ios uitableview

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *reuseIdentifier = @"cellReuse";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
        }

        NSManagedObject *manageObject = [self.fetchResultController objectAtIndexPath:indexPath];
        cell.textLabel.text = [manageObject valueForKey:@"title"];
        cell.detailTextLabel.text = [manageObject valueForKey:@"subtitle"];

        return cell;
}

我从一本书中读到,单元格是一种“可重用的视图”。我在理解“可重用”方面遇到了一些问题。

有人可以用一种简单的方式解释细胞的机制吗?

4 个答案:

答案 0 :(得分:12)

问题:表视图可能有数千行(或数百万行,无论如何)。为每个数据行创建一个单独的单元格将是繁琐和浪费的。相反,表视图仅询问与屏幕上同时显示的行数(通常不超过10-15-20个单元格)。这是可管理的,不会占用大量内存,并且无论如何都不能在显示器上看到所有行。

因此,当表视图需要显示一个新单元格时(因为用户已经滚动了视图),它需要一个超出可见区域的单元格,并将其排队到最后,重新使用它。 / p>

答案 1 :(得分:5)

一些事实

  1. 表中可见的所有单元格都有一个UITableViewCell
  2. UITableView只有当单元格移出可视窗口时才会将单元格放入可重用的队列中。
  3. 第一次使用Nib文件加载表中的所有可见单元格(7,8,10次,具体取决于单元格的高度)。
  4. 一旦你开始滚动表,就是当UITableView开始将UITableViewCells放入可重用队列时,可以在表的其他位置重复使用。

    为什么在dequeueReusableCellWithIdentifier引用中没有解释这种行为真是太神奇了。可能是因为它显而易见......这篇文章专门针对那些和我一样朦胧的人。

答案 2 :(得分:1)

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSString *cellID=@"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
  if (cell == nil)
  {
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
       cell.textLabel.text= [NSString stringWithFormat:@"%d", indexPath.row];
  }
  else
  {
     cell.textLabel.text = @"reused";
  }

  return cell;
}

要了解单元可重用性,请运行上面的代码。假设我们有50行从 cellForRow 返回50。我们可以看到表视图只创建了11个单元格(0-15)。向上/向下滚动时,tableView将重用已创建的单元格。这种可重用的表视图机制可以节省大量内存。它不会创建不必要的单元格,总是重用非可见单元格

答案 3 :(得分:1)

除了H2CO3之外,正如您所看到的,您使用了一个名为reuseIdentifier的变量,并且您正在使用以下行:

static NSString *reuseIdentifier = @"cellReuse";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier];
}

让我们一行一行:

  • 第一行指定一个静态的标识符,因此它只会构造一次。如果它不是静态的,那么每次发送消息时都会创建一个消息(这很多),如同 Lou Franco说。

  • 然后是第二个包含dequeueReusableCellWithIdentifier的重要行。这个方法加载出一个不再可见的单元格,就像双向链接列表一样,确保不在视图中的单元格的可重用性(这意味着只有那些单元格保留在内存中,对你来说是可见的,这是可重用性)。

  • 现在您可以看到“if block”的作用是什么,如果没有单元格出列,那么它会创建一个带有reuseIdentifier的新单元格,以便在它不再可见时可以重复使用。

最后,您不必担心哪个单元格有资格重用,tableView类会根据tableView帧大小和单元格高度来计算它。