【问题标题】:UILabel (CALayer) is using large amounts of virtual memoryUILabel (CALayer) 正在使用大量虚拟内存
【发布时间】:2014-06-30 13:22:17
【问题描述】:

Xcode and Instruments 中,我看到 UILabel (CALayer) 使用大量虚拟内存(匿名 VM)。我看到每个 UILabel 大约有 235 KB 的虚拟内存。

我认为这可能是 iOS 7.1 或 7.1.1 的一个新问题。

这是预期的吗?

我创建了一个简单的程序,它创建了 500 个 UILabelsInstruments 显示使用了 115MB 的内存。在大约 1500 个标签时,应用程序被操作系统终止。

for (int i = 0; i < 500; i++)
{
    index = (int)[self.items count];
    index++;

    frame = CGRectMake(10.0, 20, 300.0, 50.0);

    UILabel *newLabel = [[UILabel alloc] initWithFrame:frame];
    newLabel.text = [NSString stringWithFormat:@"This is text for label: %d", index];
    newLabel.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:newLabel];

    [self.items setObject:newLabel forKey:[NSNumber numberWithInteger:index]];
}

想法?

【问题讨论】:

    标签: ios xcode virtual-machine instruments anonymous


    【解决方案1】:

    在向 Stack Overflow 或 Apple 报告此类事情时,您确实应该消除不必要的多余代码。这段代码足以重现该现象:

    for (int i = 0; i < 500; i++)
    {
        CGRect frame = CGRectMake(10.0, 20, 300.0, 50.0);
        UILabel *newLabel = [[UILabel alloc] initWithFrame:frame];
        newLabel.backgroundColor = [UIColor whiteColor];
        [self.view addSubview:newLabel];
    }
    

    这会导致应用在我的机器上使用 129MB。 (无需使用 Instruments:Xcode 现在直接显示内存使用情况。)

    我的第一反应是:“我想我并不觉得这很令人惊讶。如果将frame 更改为更小的矩形,则使用的内存更少。视图很昂贵!它们由位图支持。”

    但是,如果将 UILabel 更改为纯 UIView,则仅使用 13MB。我认为这是足以保证提交错误的差异。

    【讨论】:

    • 但是,Apple 可能会告诉您,没有一个头脑正常的人会使用 500 个标签。毕竟,这就是表格重用其单元格的原因;你可以有一个 1000 行的表格,但它只包含大约 12 个实际单元格(因此,如果每行有一个标签,则只有大约 12 个实际标签)。
    • 我认为这个答案不准确。我无法想象视图是由位图支持的。也许标签是,但如果每个视图都是,我会感到惊讶。你有这个链接吗?
    • @kritzikratzi 我没有说视图由位图支持。我说我的第一反应是说他们是。我对它的工作原理的理解来自各种 WWDC 视频,Apple 实际上在其中谈论了支持视图的位图。
    • 我认为如果您对图层进行栅格化或使用 uilabel,它仅由位图支持。不为其他观点。我的猜测是这不是一个错误,而是一个性能问题(渲染文本非常昂贵,所以总是光栅化标签是有意义的)
    • @kritzikratzi on iOS 7+ UILabel 始终由纹理支持,无论光栅化设置如何。你可以通过分配一个 UILabel 来证明这一点,然后将其缩放得非常大,或者将边界更改得非常大,然后观察内存使用量上升或应用程序崩溃。
    【解决方案2】:

    UILabel,并且任何使用drawRect的视图(至少在iOS 7+上)都是由纹理支持的,所以每个UILabel都会使用大量内存,标签越大,使用的内存就越多。

    我发现这在我的 You Doodle 的照片编辑扩展程序中特别痛苦,它允许在照片应用程序中添加文本。不幸的是,我不得不极大地限制文本的比例范围,因为与常规应用相比,照片扩展在崩溃之前对内存使用的限制要大得多。

    这可以很容易地通过运行工具和分配一堆大的 UILabel 并设置它们的文本并确保它们都是可见的来验证,即:

    CGRect f = CGRectMake(0.0.0f, 0.0f, 300.0f, 300.0f);
    for (NSInteger i = 0; i < 100; i++)
    {
        UILabel* l = [[UILabel alloc] initWithFrame:f];
        l.backgroundColor = UIColor.blueColor;
        l.textColor = UIColor.whiteColor;
        l.text = @"UILabel text for the memory test";
        l.numberOfLines = 0;
        [self.view addSubview:l];
    }
    

    【讨论】:

      猜你喜欢
      • 2012-10-16
      • 2023-03-06
      • 2011-03-25
      • 1970-01-01
      • 2016-09-26
      • 2012-02-13
      • 2018-11-12
      • 2013-10-21
      • 1970-01-01
      相关资源
      最近更新 更多