NIB 文件中的内存管理和 UIImageView
我创建了一个示例应用程序,其中我将基本的全屏 UIImageView 设置为背景。这个应用程序非常简单。全部只有 2 页。 (我将在下面发布代码)。 NIB仅作为UIImageView。我尝试了 2 种不同的场景 -
释放 NIB 文件和图像是否存在问题。
我遇到过一些内存泄漏。
1) 示例 1 (BAD) - 我将图像直接加载到 NIB 中。当我推动视图时,内存增加了 5MB。当我(使用 NavigationController)将视图从顶部弹出时,内存仅减少了 1.5MB。 Dealloc 确实被调用了。我没有 IBOutlet。所以,对我来说,这要么是缓存,要么是将该图像保留在内存中的某个地方。
2) 示例 2(好)- 为 UIImage 视图设置一个 IBOutlet,然后将图像放入 UIImageview 中,如下所示(我知道我可以以编程方式创建 UIImageView,但我在这里测试内存而不是我的屏幕创建技能)。这本身就可以很好地清理。它从内存中删除图像,我可以在仪器中看到内存下降。
@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]];
}
I created a sample application that where I have a basic fullscreensize UIImageView set as the background. This app is very simple. All it is is 2 pages. (I will post the code below). The NIB only as UIImageView. I have tried 2 different scenarios -
Is there a problem with releasing NIB files and images.
I have been experiencing some memory leaks.
1) Example 1 (BAD)- I load the image directly in to the NIB. When I push the view, memory goes up by 5MB. When I pop (using NavigationController) the View off of the top, memory only goes down by a 1.5MB. Dealloc is indeed called. I have no IBOutlets. So, to me this is either caching or retaining this image in memory somewhere.
2) Example 2 (GOOD)- Set an IBOutlet for the UIImage view and I put the image in the UIImageview as shown below(I know I could create the UIImageView programmatically, but I am testing memory here not my screen creation skills). This cleans up nicely after itself. It removes the image from memory and I can see in Instruments that memory goes down.
@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]];
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通过 NIB 加载图像可能会出现问题——众所周知,由于缓存行为,它会“泄漏”,但这是设计使然——请参阅 这个问题。此缓存对于在 UITables 中显示小图像(高性能)很有用,但不适合将单个大图像加载到 UI 中。
我们需要查看您的更多代码!
getImage
是如何定义的?如果您在自己的代码中的任何位置使用
UIImage imageNamed:
,您应该知道它会将加载的图像缓存在内存中。释放这样的图像实际上不会卸载内存中的缓存图像!有关更多信息,请参阅:
[UIImage imageNamed...] 和 [UIImage imageWithData.. .]?
Loading images via the NIB can be problematic -- it's known to 'leak' due to caching behaviour, but this is by design -- please see this question. This caching is useful for showing small images in UITables (high performance), but not good for loading a single huge image into your UI.
We need to see more of your code! How is
getImage
defined?If you're using
UIImage imageNamed:
anywhere in your own code, you should be aware that it caches loaded images in memory. Dealloc'ing such an image won't actually unload the cached image in memory!For more info, please see:
Difference between [UIImage imageNamed...] and [UIImage imageWithData...]?
在场景 2 中,您还应该在将其设置为 nil 之前释放 backimage...
并请将代码发布到加载/初始化 UIViewController 子类的位置...
以及释放它的位置...
我的意思是,我们看到里面加载的对象你的类,但当你加载和使用你的类时,问题可能出在它之外(应用程序委托? rootMainUIViewController / 导航控制器?)
in scenario 2 you should also release backimage before to set it to nil...
and please post the code where you load/init your UIViewController subclass...
and where you release it...
i mean, we see the objects loaded inside your class, but the problem could be outside it, when you load and use your class (application delegate? a rootMainUIViewController / navigation controller?)