【问题标题】:Memory Management and UIImageViews in NIB filesNIB 文件中的内存管理和 UIImageViews
【发布时间】:2011-07-15 23:56:58
【问题描述】:

我创建了一个示例应用程序,其中我有一个基本的全屏 UIImageView 设置为背景。这个应用程序非常简单。它只有 2 页。 (我将在下面发布代码)。 NIB 只能作为 UIImageView。我尝试了 2 种不同的场景 -

释放NIB文件和图像是否有问题。

我遇到了一些内存泄漏。

1) 示例 1 (BAD)- 我将图像直接加载到 NIB。当我推送视图时,内存增加了 5MB。当我弹出(使用 NavigationController)顶部的 View 时,内存只减少了 1.5MB。确实调用了 Dealloc。我没有 IBOutlets。所以,对我来说,这要么是缓存这个图像,要么是在内存中的某个地方保留这个图像。

2) 示例 2 (GOOD)- 为 UIImage 视图设置一个 IBOutlet 并将图像放入 UIImageview 中,如下所示(我知道我可以通过编程方式创建 UIImageView,但我在这里测试的是内存而不是我的屏幕创建技能)。这会很好地清理自己。它从内存中删除图像,我可以在 Instruments 中看到内存下降。

@interface Page3VC : UIViewController {
    UIImageView*backimage;
}
@property(retain, nonatomic) IBOutlet UIImageView*backimage;
end

-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];

    backimage.image = [self getImage:@"hipHome.png"];
}
-(void)viewDidDisappear:(BOOL)animated {
    backimage.image = nil;

    [super viewDidDisappear:animated];
}

-(UIImage*)getImage:(NSString*)imageName{
    //return [UIImage imageNamed:imageName];
    return [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:imageName ofType:nil]];
}

【问题讨论】:

  • 你能显示getImage:的内容吗,我怀疑我知道其中的区别,但我不能确定。
  • 我添加了getImage。谢谢 - 我根据下面提到的链接 Oculus 添加了 getImage。

标签: iphone ipad memory memory-leaks uiimageview


【解决方案1】:

在场景 2 中,您还应该在将其设置为 nil 之前释放背景图像...

请在您加载/初始化 UIViewController 子类的位置发布代码...

以及你释放它的地方......

我的意思是,我们看到在您的类中加载了对象,但问题可能在它之外,当您加载和使用您的类时(应用程序委托?rootMainUIViewController / 导航控制器?)

【讨论】:

    【解决方案2】:

    通过 NIB 加载图像可能会出现问题——众所周知,由于缓存行为会“泄漏”,但这是设计使然——请参阅this question。这种缓存对于在 UITables 中显示小图像(高性能)很有用,但不适合将单个大图像加载到 UI 中。

    我们需要查看更多您的代码! getImage是如何定义的?

    如果您在自己的代码中的任何地方使用UIImage imageNamed:,您应该知道它会将加载的图像缓存在内存中。释放这样的图像实际上不会卸载内存中的缓存图像!

    更多信息,请参见:

    Difference between [UIImage imageNamed...] and [UIImage imageWithData...]?

    【讨论】:

    • 我在上面添加了getImage方法(不使用ImageNamed)。
    • @smcdrc 没办法清除我听说过的图片缓存!
    • @smcdrc 感谢您添加 getImage 方法。我可以看到您以 在后台缓存的方式使用 UIImage,因此这与您的问题描述相匹配并向我确认了我的原始答案 - 即加载的图像一个 NIB 是通过 imageNamed 方法加载的,该方法在后台进行缓存,这是这里的关键区别。
    • @smcdrc 请查看此问题的最佳答案:stackoverflow.com/questions/289360/… 它详细介绍了一种解决方法,可让您仍然在 NIB 中定义内容(但推迟加载图像,直到在您自己的代码中,您可以使用非缓存方式加载图片)。
    • 标记了我的结帐答案,看起来像是另一个报复性的投反对票。
    猜你喜欢
    • 2011-04-08
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    • 2016-10-12
    相关资源
    最近更新 更多