为啥将按钮添加为子视图时会出现内存泄漏?

Posted

技术标签:

【中文标题】为啥将按钮添加为子视图时会出现内存泄漏?【英文标题】:Why do I get a memory leak when adding a button as a subview?为什么将按钮添加为子视图时会出现内存泄漏? 【发布时间】:2010-02-22 19:04:12 【问题描述】:

我有一个使用 tableview 的应用程序,以及一个 UIButton,我将它作为子视图添加到每个自定义单元格,如下所示:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

    checkButton = [[UIButton buttonWithType:UIButtonTypeCustom] initWithFrame:CGRectMake(2.0, 2.0, 40.0, 40.0)];
    [cell.contentView addSubview:checkButton];

    // lot's of other code

    return cell;

我认为一切都很好,直到我开始使用 Instruments 来确保我没有任何内存泄漏,但我发现像这样将 UIButton 添加为单元格的子视图会导致 UIKit 中的泄漏。

具体来说,我得到每个单元格行的内存泄漏(每次将按钮添加为子视图),泄漏的对象是“CALayer”,负责的框架是“-[UIView _createLayerWithFrame:]”。

我在这里做错了吗?

【问题讨论】:

【参考方案1】:

代码 [UIButton buttonWithType] 方法已经包含一个 initWithFrame 方法。你只需要使用一个CGRectMake,然后设置按钮的框架。

rectangle = CGRectMake(2.0f,2.0f,40.0f,40.0f);
checkButton = [UIButton buttonWithType:UIButtonTypeCustom];
checkButton.frame = rectangle;

【讨论】:

解决了!谢谢您的帮助。 (伙计,你们的反应很快,呵呵) 请注意,添加“UIButton *checkButton =" 会导致我的应用程序崩溃...但让它保持原样 ("checkButton =") 似乎可以正常工作。 抱歉,看来您必须在标题中声明它。如果允许,我将编辑我的评论!【参考方案2】:

您是否在物理设备模拟器上对此进行了测试?

已知模拟器与实际设备代码相比存在一些内存管理变化。 您应该始终在真实设备上运行内存泄漏测试。

否则,您的代码在我看来是正确的。

【讨论】:

【参考方案3】:

checkButton 是你班级的@property(retain) 吗?

因为在这种情况下,您应该在使用后将属性设置为 null...但是您不能这样做,因为单元格的单元格生命周期不受您的控制;使用局部变量会更好。

此外,您应该在 addSubview 之后放置一个 [checkButton release],因为 addSubview 代码会自己保留/释放

【讨论】:

不,你不应该打电话给[checkButton release],因为它从未被分配、新建或复制。但是,如果它是一个保留的属性,那么将它归零是一个很好的观点。 按钮是自动释放的,因为它是通过类方法创建的。 我错过了自动释放,抱歉。 Jawboxer 没有使用属性设置器。所以没有理由发布。

以上是关于为啥将按钮添加为子视图时会出现内存泄漏?的主要内容,如果未能解决你的问题,请参考以下文章

仪器报告内存泄漏。不明白为啥

为啥 QApplication 会出现内存泄漏?

RxSwift 为啥我们没有调用 dispose 会有内存泄漏

为啥苹果提供的 SimpleFTPSample 会泄漏内存?

开发问题火狐出现内存泄漏错误

ARKit ARSCNView.snapshot() 内存泄漏