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

时间:2013-09-27 15:49:46

标签: ios memory crash screen capture

我现在正在编写一个程序来捕获屏幕并转换为视频。如果视频少于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
// });


}

1 个答案:

答案 0 :(得分:2)

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

但我认为你想恢复你的CFRelease(imageData)。这是CGDataProviderCopyData创建的对象,因此您拥有它并且必须清理。

我还认为您必须在pixelBuffer之后发布使用CVPixelBufferCreateWithBytes创建的appendPixelBuffer。您可以使用CVPixelBufferRelease功能。

Core Foundation内存规则是,如果函数名称中包含CopyCreate,则您拥有该对象并负责释放它。请参阅内存管理编程指南(适用于Core Foundation)中的Create Rule

我原以为Xcode“Product”菜单中的静态分析器( shift + command + B 或“Analyze”)本来会发现这个问题,因为它在寻找核心基金会内存问题方面做得更好(尽管不完美)。

或者,如果您通过Instruments中的Leaks工具运行您的应用程序(它也会同时显示分配工具),您可以查看您的内存使用情况。虽然视频捕获需要大量的Live Bytes,但根据我的经验,它仍然非常平淡。如果它在增长,你就会在某个地方泄漏。