捕获屏幕并保存到视频ios时收到内存警告

捕获屏幕并保存到视频ios时收到内存警告,ios,memory,crash,screen,capture,Ios,Memory,Crash,Screen,Capture,我现在正在写一个程序来捕获屏幕并转换成视频。如果少于10秒,我可以成功保存视频。但是,如果超过这个范围,我会收到内存警告和应用程序崩溃。我编写了如下代码。我在哪里错过了发布数据的机会?我想知道怎么做 -(void)captureAndSaveImage { if(!stopCapturing){ if (assetWriterInput.readyForMoreMediaData) { keepTrackOfBackGroundMood++; NSLog(@"keepTrac

我现在正在写一个程序来捕获屏幕并转换成视频。如果少于10秒,我可以成功保存视频。但是,如果超过这个范围,我会收到内存警告和应用程序崩溃。我编写了如下代码。我在哪里错过了发布数据的机会?我想知道怎么做

-(void)captureAndSaveImage
{

if(!stopCapturing){

if (assetWriterInput.readyForMoreMediaData)
{
    keepTrackOfBackGroundMood++;
    NSLog(@"keepTrackOfBackGroundMood is %d",keepTrackOfBackGroundMood);

    CVReturn cvErr = kCVReturnSuccess;

    CGSize imageSize = screenCaptureAndDraw.bounds.size;


    CGFloat imageScale = 0; //if zero, it reduce processing time

    if (NULL != UIGraphicsBeginImageContextWithOptions)
    {
        UIGraphicsBeginImageContextWithOptions(imageSize, NO, imageScale);
    }
    else
    {
        UIGraphicsBeginImageContext(imageSize);
    }

    [self.hiddenView.layer renderInContext:UIGraphicsGetCurrentContext()];

    [self.screenCaptureAndDraw.layer renderInContext:UIGraphicsGetCurrentContext()];


    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();



     image = (CGImageRef) [img CGImage];

    CVPixelBufferRef pixelBuffer = NULL;
    CFDataRef imageData= CGDataProviderCopyData(CGImageGetDataProvider(image));
    cvErr = CVPixelBufferCreateWithBytes(kCFAllocatorDefault,
                                         FRAME_WIDTH2,
                                         FRAME_HEIGHT2,
                                         kCVPixelFormatType_32BGRA,
                                         (void*)CFDataGetBytePtr(imageData),
                                         CGImageGetBytesPerRow(image),
                                         NULL,
                                         NULL,
                                         NULL,
                                         &pixelBuffer);


    //CFRelease(imageData);
    //CGImageRelease(image);  //I can't write this code because I am not creating it and when I check online, it say it is not my responsibility to release. If I write, the application crash immediately


    // calculate the time
    CFAbsoluteTime thisFrameWallClockTime = CFAbsoluteTimeGetCurrent();
    CFTimeInterval elapsedTime = thisFrameWallClockTime - firstFrameWallClockTime;


    // write the sample

    BOOL appended = [assetWriterPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:presentationTime];

    if (appended) {
        NSLog (@"appended sample at time %lf and keepTrackofappended is %d", CMTimeGetSeconds(presentationTime),keepTrackofappended);
        keepTrackofappended++;
    } else {
        NSLog (@"failed to append");
        [self stopRecording];
        //self.startStopButton.selected = NO;
        screenRecord=false;
    }



}

}//stop capturing
// });


}

我同意您不想做
CGImageRelease(image)
。此对象是通过调用
UIImage
对象的
CGImage
方法创建的。因此,所有权未转移,ARC仍对您的
img
对象进行内存管理,无需释放
图像
对象

但我认为您确实希望恢复您的
CFRelease(imageData)
。这是一个由
CGDataProviderCopyData
创建的对象,因此您拥有它,必须清理它

我还认为,在
appendPixelBuffer
之后,必须释放使用
CVPixelBufferCreateWithBytes
创建的
pixelBuffer
。您可以使用
CVPixelBufferRelease
功能进行此操作

核心基础内存规则是,如果函数在代码中有<代码>拷贝<代码>或<代码>创建< /代码>,则拥有该对象并负责释放该对象。参见内存管理编程指南中的核心基础。

<>我想静态分析器(Shift + Strue+B或从XCODE“产品”菜单中的“分析”)已经确定了这个问题,因为它在找到核心基础内存问题方面已经做得更好了(虽然不是完美的)。p>
或者,如果您通过Instruments中的Leaks工具运行应用程序(同时还会显示Allocations工具),您可以查看内存使用情况。虽然视频捕获需要大量的实时字节,但根据我的经验,它仍然非常平坦。如果它在增长,你会在某个地方漏个洞

您一定在某个地方有泄漏(至少,我会取消注释
CFRelease(imageData)
,不要忘记
CVPixelBufferRelease
)。我刚刚测试了一个1200帧的截图,它在我的iPhone5上很好。当我在仪器中测试时,分配是平的,所以除非你有泄漏,否则你应该没事。哦,谢谢,罗伯。你真的帮了我。我认为它现在解决了内存泄漏问题。我将使用静态分析器再次检查。@user1111是,
CFRelease(imageData)
CVPixelBufferRelease(pixelBuffer)
(但不是
CGImageRelease(image)
)应该可以修复泄漏。