调用 reloadData 时自定义 UITableViewCell 内存泄漏
Posted
技术标签:
【中文标题】调用 reloadData 时自定义 UITableViewCell 内存泄漏【英文标题】:custom UITableViewCell memory leak when calling reloadData 【发布时间】:2014-06-09 09:24:16 【问题描述】:我有一个加载一些自定义 UITableViewCells 的 UITableView。这些自定义单元格分配一些 UIButton,并将这些按钮添加到自定义单元格的 contentView。在 tableView 上重复调用 reloadData 时,这些 UIButton 似乎正在慢慢泄漏内存。我正在使用 ARC,ios 7。
这里是创建单元格的地方:
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *simpleTableIdentifier = @"PostCell";
PostCell *cell = [_tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
cell = [[PostCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
return cell;
这是自定义单元格的 init 方法:
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self)
self.height = 0;
self.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self addInteractionContainer];
return self;
最后是 addInteractionContainer 方法(如果我不调用这个方法,我看不到泄漏):
- (void)addInteractionContainer
//interaction container
UIView* interactionContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 80)];
[interactionContainer setBackgroundColor:[UIColor ProseSepiaColor]];
//like button
LikeButton* likeButton = [[LikeButton alloc] initWithFrame:CGRectMake(10, 10, 75, 30) liked:([post.yourVote intValue] > 0)];
[likeButton addTarget:self action:@selector(likePost:) forControlEvents:UIControlEventTouchUpInside];
[interactionContainer addSubview:likeButton];
//comment button
CommentButton* commentButton = [[CommentButton alloc] initWithFrame:CGRectMake(likeButton.frame.origin.x + likeButton.frame.size.width + 10,
10, 105, 30)];
[commentButton addTarget:self action:@selector(segueToComments:) forControlEvents:UIControlEventTouchUpInside];
[commentButton setNumComments:self.post.numComments];
[interactionContainer addSubview:commentButton];
[self.contentView addSubview:interactionContainer];
self.height += interactionContainer.frame.size.height;
【问题讨论】:
正如您所说,当您不调用 addInteractionContainer 时,您不会泄漏。您可以使用 UIButton 进行测试,以便我们可以确认 Like 按钮类或评论类的子类化有问题 您可以使用泄漏工具来尝试识别问题,但您的 addInteractionContainer 看起来并不“正确”。它正在添加事件处理程序并引用数据 - “self.post.numComments”,即使此时无法设置此属性。您应该在单元格构造函数中添加 UI 元素并通过属性公开这些元素。然后,您可以在 tableview 控制器中添加操作处理程序和内容 我确实尝试过只使用一个基本的 UIButton 而没有额外的数据,同样的问题发生了。 【参考方案1】:try this
- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *simpleTableIdentifier = @"PostCell";
PostCell *cell = [_tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if(cell!=nil)
cell=nil;
if (cell == nil)
cell = [[PostCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
return cell;
【讨论】:
以上是关于调用 reloadData 时自定义 UITableViewCell 内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章
UITableView 没有在 reloadData 上重新加载
使用 NSFetchedRequestController 更新 UITableView 行和部分,而不使用 reloadData
使用 UITableView 的可变高度自定义单元格调用 reloadData 时保持 UITableView 的当前位置