由于已知原因的内存压力终止,未知的解决方案 [英] Termination due to memory pressure with known cause, unknown solution

查看:127
本文介绍了由于已知原因的内存压力终止,未知的解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于应用程序使用中某个时刻的内存压力,我的应用程序正在终止,我已将问题分解为造成问题的一大块代码。

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. 离开视频列表

  3. 重复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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆