捕获屏幕并保存到视频 ios 时收到内存警告
Posted
技术标签:
【中文标题】捕获屏幕并保存到视频 ios 时收到内存警告【英文标题】:Received memory warning when capturing screen and save to video ios 【发布时间】:2013-10-04 00:02:08 【问题描述】:我现在正在编写一个程序来捕获屏幕并转换为视频。如果少于 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
// );
【问题讨论】:
你肯定在某处有泄漏(至少,我会取消注释CFRelease(imageData)
并且不要忘记 CVPixelBufferRelease
)。我刚刚测试了 1200 帧捕获,在我的 iPhone 5 上很好。当我在 Instruments 中测试时,分配是平坦的,所以除非你有一些泄漏,否则应该没问题。
【参考方案1】:
我同意你不想做CGImageRelease(image)
。该对象是通过调用UIImage
对象的CGImage
方法创建的。因此所有权没有转移,ARC 仍然为您的 img
对象进行内存管理,并且不需要释放 image
对象。
但我认为您确实想要恢复您的CFRelease(imageData)
。这是由CGDataProviderCopyData
创建的对象,因此您拥有它并且必须清理它。
我还认为您必须在 appendPixelBuffer
之后发布您使用 CVPixelBufferCreateWithBytes
创建的 pixelBuffer
。您可以为此使用CVPixelBufferRelease
函数。
Core Foundation 内存规则是,如果函数名称中包含 Copy
或 Create
,则您拥有该对象并负责释放它。请参阅Core Foundation 的内存管理编程指南中的Create Rule。
我原以为静态分析器(shift+command+B 或 Xcode“产品”菜单中的“分析”)会发现这个问题,因为它在发现 Core Foundation 内存问题方面做得更好(尽管并不完美)。
或者,如果您通过 Instruments 中的 Leaks 工具运行您的应用程序(同时还会向您显示 Allocations 工具),您可以查看您的内存使用情况。虽然视频捕获需要大量 Live Bytes,但根据我的经验,它保持相当平淡。如果它在增长,则说明某处有泄漏。
【讨论】:
哦,谢谢罗伯。你真的帮了我。我认为它现在解决了内存泄漏问题。我会用静态分析器再次检查。 @user1111 是的,CFRelease(imageData)
和 CVPixelBufferRelease(pixelBuffer)
(但不是 CGImageRelease(image)
)应该修复泄漏。以上是关于捕获屏幕并保存到视频 ios 时收到内存警告的主要内容,如果未能解决你的问题,请参考以下文章
在 UICollectionView iOS 7 中收到内存警告
NSuncaughtexceptionhandler 没有捕获内存警告崩溃