【问题标题】:Memory issue in iPhone?iPhone内存问题?
【发布时间】:2009-05-15 10:37:16
【问题描述】:

我使用单个 UIImageView 对象,分配一次内存。但是多次更改图像名称。 问题是,

A) 一个 UIImageView 对象,分配一次并且永远不会更改图像名称。 例如 UIImageView *firstObj = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"blue.png"]];

B) 另一个 UIImageView 对象,分配一次并多次更改图像名称

例如 UIImageView *secondObj = [[UIImageView alloc]initWithImage:[UIImage imageNamed:@"blue.png"]];

//更改图像名称一次,

secondObj.image = [UIImage imageNamed:@"green.png"];

 and so on....

哪些对象使用最大内存或使用相同内存?

在内存利用率最低的情况下,使用 secondObj 的最佳方式是什么?

请简要解释一下,因为我需要在我的项目中使用图像数量,并且我想避免由于图像引起的内存问题。

【问题讨论】:

    标签: iphone objective-c


    【解决方案1】:

    重新格式化你的代码,你的第二个例子是:

    UIImageView *secondObj = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"blue.png"]];
    // changed image name once
    secondObj.image = [UIImage imageNamed:@"green.png"];
    // and so on....
    

    这段代码很好。当您将图像分配给 UIImageView 的实例时,它会将图像的保留计数增加一。如果一个图像已经被分配,它将首先释放它。

    由于 [UIImage imageNamed:...] 将为您提供已标记为自动释放的对象,您可以继续分配图像,如示例所示,不会出现内存泄漏。一旦 UIImageView 释放现有的图像,它就会被一个自动释放池收集。

    在最小化内存使用方面,[UIImage imageNamed:...] 方法确实将图像存储在少量应用程序范围的高速缓存中,您不施加任何直接控制超过。缓存确实有上限,但你不能刷新它来回收内存,所以在你获取新的 UIImage 时使用它会增加你的内存占用。

    您可能需要考虑通过使用 [UIImage imageWithData:...] 来加载您的图像来避免此缓存,这在 Stackoverflow 问题 [UIImage imageNamed…] vs [UIImage imageWithData…] 中进行了讨论.

    【讨论】:

    • 其他人指出 imageNamed: 由于缓存问题,对内存消耗非常不利。我什至会使用 initWithData: 手动初始化 UIImage:并在 UIImageView 初始化或 UIImageView 图像更改后立即释放它,只是为了避免在自动释放池中堆积。
    【解决方案2】:

    我不是出色的 Objective-C 专家,但您在 B 中的使用看起来应该可以正常工作而不会泄漏。由于没有其他对象(UIImageView 除外)保留 UIImage,因此当它们在 UIImageView 中被替换时应该释放它们,并且垃圾收集器应该完成它的工作。

    大卫

    【讨论】:

    • 谢谢大卫,你能简单解释一下吗?
    【解决方案3】:

    使用 +imageNamed: 创建的 UIImage 是自动释放的,因此它会消失。举个例子:

    UIImage *image1 = [UIImage imageNamed:@"blue.png"]; //image1 has retain count 1
    [myImageView setImage:image1]; //image1 is retained by UIImageView so has retain count 2
    
    //run loop ends, all auto released objects are released and image1 now has retain count 1
    
    //Later in app
    
    UIImage *image2 = [UIImage imageNamed:@"green.png"]; //image2 has retain count 1
    [myImageView setImage:image2]; //image1 is released and now has retain count 0, so the memory is freed, image2 now has retain count 2 as it is retained 
    

    【讨论】:

      【解决方案4】:

      由于没有其他对象(UIImageView 除外)保留 UIImage,因此在 UIImageView 中替换它们时应该释放它们,并且垃圾收集器应该完成它的工作。

      请记住,iPhone 上没有垃圾收集器。 您可以在此处找到更多相关信息:
      StackOverflow:Is garbage collection supported for iPhone applicaions?

      (这实际上应该是对戴维斯回答的评论,但我还没有足够的声誉)

      【讨论】:

        猜你喜欢
        • 2012-07-22
        • 1970-01-01
        • 2011-01-07
        • 2011-11-12
        • 2011-04-11
        • 2011-04-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多