1

我有一个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:UILabel使用self.label_1 = (UILabel*)[cell viewForTag:5];//5 is the Tag value i have setup using IB.

到目前为止一切都很好。现在,当我运行这个应用程序时,我看到直到 16 的属性都有正确的值,其余的都是空的。这是因为仅绘制了前 16 个单元格,因此剩余的属性仍未分配相应的UILabel. 到这里为止一切都很好。现在,当我滚动表格时,剩余的 4 个单元格在屏幕上,前 4 个单元格在屏幕外。现在,当我打印(使用NSLog(@"%@",self.label_1.text).)每个属性的值时,我发现屏幕上对应标签的属性输出正确的值,而屏幕外的属性输出随机值(不是 null,只是随机值,可以关闭其他属性也是。)

在正常情况下,我首先想到的是,一旦行离开屏幕,它们就会被释放,因此属性现在指向某个随机位置(悬空指针)。但是在我的例子中,属性是strong这样的,所以在这个指针存在之前,对应的 UILabel 不应该被释放。谁能解释一下这里发生了什么?

4

2 回答 2

2

为了节省内存,UITableView回收UITableViewCells. 当你打电话时,你正在回收细胞tableView dequeueReusableCellWithIdentifier:

我的猜测是label_1 == label_17,label_2 == label_18等。

如果您需要更新这些标签,则需要重新考虑您的设计。所有更新都需要在tableView:cellForRowAtIndexPath:. 当您需要更新单元格中的数据时,您需要调用,并在您的方法中[tableView reloadData]设置标签的正确值。tableView:cellForRowAtIndexPath:UITableViewDataSource

于 2013-10-04T17:26:33.907 回答
0

细胞正在被重复使用。假设 10 个单元格可以容纳一个屏幕。向下滚动时,第一个单元格将消失,第十一个单元格将出现,依此类推。tableview 不是为每个单元格创建新视图,而是保留一个队列并将单元格从队列中取出。这意味着您在第五行的单元格也可以用于显示第十六行或任何其他行。当它离开屏幕时,您实际上并不知道或控制单元格视图(及其子视图),并且您不应该在动态单元格中保留指向视图的强指针。如果你的细胞是静态的,那就完全没问题了。相反,将您的逻辑移动到 tableView:cellForRowAtIndexPath:。这样,您就知道具有特定 indexPath 的单元格已出现在屏幕上,您可以采取相应的行动。

于 2013-10-04T19:59:05.677 回答