由于已知原因的内存压力终止,未知的解决方案 [英] Termination due to memory pressure with known cause, unknown solution
问题描述
由于应用程序使用中某个时刻的内存压力,我的应用程序正在终止,我已将问题分解为造成问题的一大块代码。
My app is terminating due to memory pressure at a certain point in the app's use, and I have isolated the problem down to one chunk of code that is causing the problem.
我将复制下面的代码块,但首先我会描述它正在做什么。
I'll copy the code chunk below, but first I'll describe what it's doing.
描述:
我有一个迭代通过a的for循环视频列表。对于每个视频,for循环增加包含滚动视图的大小,绘制标签和按钮(均与视频有关),并异步抓取视频的缩略图并将其放在按钮下方。
I have a for loop that is iterating through a list of videos. For each video, the for loop increases the size of the containing scrollview, draws a label and a button (both pertaining to the video), and asynchronously grabs a thumbnail of the video and places it below the button.
问题:
抓取缩略图部分就是问题所在。我不认为这是异步完成的事实是问题,因为我已经同步尝试并且终止仍然发生。当我注释掉抓取缩略图的代码(下面代码中的整个异步部分)时,应用程序不会崩溃。
The grabbing the thumbnail part is the problem. I don't think that the fact that this is done asynchronously is the problem, as I have tried it synchronously and the termination still occurs. When I comment out the code that grabs the thumbnail (the entire asynchronous part in the code below) the app doesn't crash.
代码:
注意:我正在使用注释来替换代码在某些情况下为了简洁起见。
NB: I'm using comments to replace code in some cases for brevity.
for (int i = [_videoURLs count]-1; i >= 0 ; i--)
{
//increase the scrollview size
//get background image:
dispatch_async(screenshotQueue, ^{
AVURLAsset *as = [[AVURLAsset alloc] initWithURL:currentURL options:nil];
AVAssetImageGenerator *ima = [[AVAssetImageGenerator alloc] initWithAsset:as];
ima.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 24);
CGImageRef imgRef = [ima copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imgRef];
dispatch_async(dispatch_get_main_queue(), ^{
UIImageView *backgroundImage = [[UIImageView alloc]initWithFrame:buttonFrame];
backgroundImage.image = thumbnail;
backgroundImage.layer.opacity = 0;
[self.videoScrollView addSubview:backgroundImage];
[self.videoScrollView sendSubviewToBack:backgroundImage];
[UIView animateWithDuration:0.5 delay:0.0 options: UIViewAnimationOptionCurveEaseInOut
animations:^{
backgroundImage.layer.opacity = 1;
}
completion:^(BOOL finished){}];
});
});
//add title to the screen caps
//draw the button
}
我正在使用Xcode 5,在iOS 7的新设备上进行测试。我是自学成才,所以我确定我已经学会了公平地分享坏习惯,但我希望我已经错过了一些明显有经验的人会接受的东西。
I'm on Xcode 5, testing on a new device with iOS 7. I'm self taught, so I'm sure I've picked up my fair share of bad habits, but I'm hoping I've missed something obvious that someone with a little more experience will pick up on.
我已经尝试了大量的谷歌搜索并搜索堆栈溢出,并尝试查看诊断,日志和内存配置文件以进一步隔离问题,无济于事。
I've tried a fair amount of googling and searching on stack overflow, and have tried looking at diagnostics, logs and memory profiles to isolate the problem further, to no avail.
非常感谢任何帮助!
编辑:
如何重现错误:
- 转到视频列表
- 离开视频列表
- 重复1 + 2 4或5次导致崩溃
步骤2.简单地从其超级视图中删除整个scrollView,然后重绘它。我知道每次回到视频列表都没有必要重新绘制视频列表,但我出于某种原因这样做,我不相信这是问题的根源(我可能是错的)。
Step 2. simply removes the entire scrollView from its superview and then redraws it. I understand it's not necessary to redraw the video list every time you go back to it, but I'm doing this for a certain reason and I don't believe this is the source of the problem (I could be wrong).
编辑2 :
以下是内存配置文件的图片:
Here's an image of the memory profile:
推荐答案
您展示的代码存在巨大泄漏。您正在创建一个Core Foundation对象:
The code you show has a huge leak. You are creating a Core Foundation object with:
CGImageRef imgRef = [ima copyCGImageAtTime:time actualTime:NULL error:&err];
但我看不到相应的 CFRelease
。
你的代码应该是:
CGImageRef imgRef = [ima copyCGImageAtTime:time actualTime:NULL error:&err];
UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imgRef];
CFRelease(imgRef);
这篇关于由于已知原因的内存压力终止,未知的解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!