UITableViewCell – 了解“可重用”

- (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; } 

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

有人能简单地解释细胞的机制吗?

问题是:一个表视图可能有成千上万行(或数百万,无论)。 为每个数据行创build一个单独的单元格将是单调乏味和浪费的。 相反,表视图只要求屏幕上同时显示的行数(通常不超过10-15-20个单元格)。 这是可以pipe理的,不会消耗大量的内存,并且不会显示所有行在显示器上可见。

所以,当表视图需要显示一个新的单元格时(因为用户已经滚动了视图),它需要一个单元离开可见区域,并将其排队回去,重新使用它。

一些事实

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

    为什么这个行为在dequeueReusableCellWithIdentifier引用中没有解释,真是太神奇了。 可能是因为很明显……这个入口是专门给那些和我一样昏暗的人。

 - (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。 我们可以看到table view只创build了11个单元格(0-15)。 当您向上/向下滚动tableView正在重新使用已经创build的单元格。 这个表视图的可重用机制节省了大量的内存。 它不会创build不需要的单元格,总是重用不可见的单元格

除了H2CO3,正如你所看到的,你已经使用了一个名为reuseIdentifier的variables,你正在使用以下几行:

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

所以让我们一行一行去:

  • 第一行指定一个静态的标识符,所以它只能被构造一次。 如果不是固定的,就像Lou Franco所说的那样,每次发送信息时都会做出一个(这是很多的)。

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

  • 现在你可以看到'if block'是做什么的,如果没有一个单元出队,那么它会用reuseIdentifier创build一个新的单元,这样当它不可见时就可以重用。

最后你不必打扰哪个单元格有资格重用,tableView类会根据tableView的框架大小和单元格高度来计算它。