我有一个UITableView
,其中包含我使用IB创建的原型单元格。我在这个原型单元格中有一个UILabel
。我已将标记值5设置为此UILabel
,以便我可以使用viewForTag:
方法识别它。
我还定义了20个这样的私人财产
@property(nonatomic, strong) UILabel *label_1;
@property(nonatomic, strong) UILabel *label_2;
.
.
.
@property(nonatomic, strong) UILabel *label_20;
现在,在从cellForRowAtIndexPath:
创建单元格时,我使用{{1}将每行的UILabel
分配给相应的属性(第1行的label_1,第2行的label_2,...等) }}
到目前为止,一切都很好。现在,当我运行这个应用程序时,我看到16之前的属性具有正确的值,其余为空。这是因为仅绘制了前16个单元格,因此仍未为其余属性分配相应的self.label_1 = (UILabel*)[cell viewForTag:5];//5 is the Tag value i have setup using IB
。
一切都很好,直到这里。现在,当我滚动表格时,剩余的4个单元格在屏幕上,前4个单元格在屏幕外。现在,当我打印(使用UILabel
。)每个属性的值时,我发现,屏幕上相应标签的属性输出正确的值,而屏幕外的属性输出随机值(非空,只是随机)价值,也可以脱离其他财产。)
在正常情况下,我想到的第一件事是,一旦行离开屏幕,它们就会被解除分配,因此属性现在指向一些随机位置(悬空指针)。但在我的情况下,属性是NSLog(@"%@",self.label_1.text)
所以相应的UILabel不应该被解除分配,直到该指针存在。有人可以解释一下这里发生的事情吗?
答案 0 :(得分:2)
为了节省内存,UITableView
会回收UITableViewCells
。当您致电tableView dequeueReusableCellWithIdentifier:
时,您正在回收单元格。
我的猜测是label_1 == label_17
,label_2 == label_18
等
如果您需要更新这些标签,则需要重新考虑您的设计。所有更新都需要在tableView:cellForRowAtIndexPath:
中完成。如果您需要更新单元格中的数据,则需要致电[tableView reloadData]
,并在tableView:cellForRowAtIndexPath:
的{{1}}方法中设置正确的标签值。
答案 1 :(得分:0)
正在重复使用细胞。假设10个单元格可以适合一个屏幕。向下滚动时,第一个单元格将消失,第十一个单元格将出现,依此类推。 tableview不是为每个单元格创建新视图,而是保留队列并使单元格从中出列。这意味着第五行中的单元格也可用于显示第十六行或任何其他行。当它离开屏幕时,您实际上并不知道或控制单元格视图(以及它的子视图),并且您不应该在动态单元格中保留强大的视图指针。如果你的细胞是静止的,它就会完全没问题。相反,将您的逻辑移动到tableView:cellForRowAtIndexPath:。这样,您就知道具有特定indexPath的单元格已出现在屏幕上,您可以采取相应的行动。