我已经创建了一个应用程序,它(好吧它已经)准备好提交了。
该应用基本上是一款面向 child 的闪存卡应用,每页有 12 张卡片。
目前仅适用于 iPad,当卡片被触摸时, ImageView 会从卡片动画到全屏,全分辨率为 2048 x 1536,它会播放动物的声音,你点击全尺寸图像,它就会出现回到卡片中。每张卡片分配有 5 张图像。该应用程序在整个设计期间一直运行完美,现在我已经加载了所有动物并且我一直在测试它并注意到它崩溃了。
长话短说,内存会以每张图片 12MB 的速度不断增长(尽管每张图片大约为 200-400KB),直到达到 700MB 内存并崩溃。此内存永远不会减少。
我已经通过 xcode 工具运行该应用程序,没有看到任何泄漏,但在“分配”中确定是“ImageIO-jpeg-data”类别是罪魁祸首。
我整晚都在阅读这篇文章,因为我发现了一些有希望的结果,但是这些结果对我没有用,所以我假设我误解了所建议的内容,或者我没有理解所以希望有人能也许可以帮我解决这个问题,或者用通俗易懂的方式解释我如何解决这个问题。
好的,下面来解释一下我是如何设置 View Controller 的。
最初我为数组中的每张卡片设置了 5 张图像,但是有延迟,所以这里有人建议我在 viewDidLoad 中预加载图像,然后在触摸卡片/按钮时调用它们。
例如,我在 viewDidLoad 中使用了这种格式
domestic100 = [UIImage imageNamed:@"ferret-00"];
domestic101 = [UIImage imageNamed:@"ferret-01"];
domestic102 = [UIImage imageNamed:@"ferret-02"];
domestic103 = [UIImage imageNamed:@"ferret-03"];
domestic104 = [UIImage imageNamed:@"ferret-04"];
然后在按下的按钮中,我通过调用将图像分配给 ImageView :
domestic01ImageContainer.image = domestic100;
在 if else 中检查图像编号是否为 1 到 4。
无论如何,它工作得很好(除了这个内存问题)
我在网上看到我最好使用
声明 uiimages[UIImage imageWithContentsOfFile:path]
如本文所示: UIImage memory not deallocating VM: ImageIO_JPEG_DATA?
所以我在代码中所做的改动是:
在我的 viewDidLoad 中,我现在这样创建 uiimages:
domestic200 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-00" ofType: @"jpg"]];
domestic201 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-01" ofType: @"jpg"]];
domestic202 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-02" ofType: @"jpg"]];
domestic203 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-03" ofType: @"jpg"]];
domestic204 = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource: @"dog-04" ofType: @"jpg"]];
然后在按下的按钮中使用将图像调用到 ImageView 中
[domestic01ImageContainer setImage:domestic100];
我得到了相同的结果 - 图像只是在同一内存中构建,而不是释放或取消分配。
我对 objective-c 不感冒,这是我的第一个真正的应用程序。
如果有人愿意抽出一点时间来帮助我,我将不胜感激。
提前致谢。
****** 编辑 ******
所以我已经告诉你我如何在上面加载我的图像,我还在 viewDidLoad 中为 12 个 ImageView 提供了一个起点和一个隐藏的 alpha。
domestic01ImageContainer = [[UIImageView alloc] initWithFrame:CGRectMake(30, 123, 152, 224)];
domestic01ImageContainer.Alpha = 0;
然后我添加 subview :
[self.view addSubview:domestic01ImageContainer];
每个 imageview 都分配了一个点击手势以在稍后隐藏图像:
UITapGestureRecognizer *domestic01Tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(imageTaped:)];
[domestic01ImageContainer addGestureRecognizer:domestic01Tap];
[domestic01ImageContainer setUserInteractionEnabled:YES];
当按下拇指/卡片时,按钮的简化版本将是:
- (IBAction)domestic01ButtonClicked:(id)sender {
static int imageNumber = 0;
if (imageNumber == 0) {
[domestic01ImageContainer setImage:domestic100];
imageNumber++;
}
else if (imageNumber == 1) {
[domestic01ImageContainer setImage:domestic101];
imageNumber++;
}
else if (imageNumber == 2) {
[domestic01ImageContainer setImage:domestic102];
imageNumber++;
}
else if (imageNumber == 3) {
[domestic01ImageContainer setImage:domestic103];
imageNumber++;
}
else if (imageNumber == 4) {
[domestic01ImageContainer setImage:domestic104];
imageNumber = 0;
}
domestic01ImageContainer.Alpha = 1;
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
domestic01ImageContainer.frame = CGRectMake(0, 0, 768, 1024);
} completion:^(BOOL finished) {
}];
我的 imageTapped 识别器将全尺寸图像缩小回我使用的卡片:
[UIView animateWithDuration:0.2 delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{
domestic01ImageContainer.frame = CGRectMake(30, 123, 152, 224);
} completion:^(BOOL finished) {
domestic01ImageContainer.Alpha = 0;
}];
基本上将闪存卡从全屏恢复为卡片/缩略图的大小,并将 alpha 再次设置为 0。
就像我说的那样一切正常,但正如您所建议的那样,图像被保留在某处。
希望这能更清楚地说明可能导致问题的原因。
在 imageTapped 中将 alpha 设置为 0 后,我曾尝试将图像设置为 nil,但这并没有清除内存。
[domestic05ImageContainer setImage:nil];
最佳答案
好吧,如果其他人遇到这个问题,那么这里是我发现非常有效的解决方案。
http://xcodenoobies.blogspot.co.uk/2011/02/best-way-to-use-uiimageview-memory.html
感谢 Anna 的意见,它为我指明了正确的方向,但他的回答为我做了这件事。
关于ios - 内存警告和崩溃 ImageIO-jpeg-data,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27452640/