![](/img/trans.png)
[英]ImagePickerController crashes my app saying “Received Memory Warning” when there are other apps running on my device (2 or more apps)
[英]“Received memory warning” while running app on device
我正在开发iPhone视频解码器应用程序。 我需要为每个帧转换原始像素数据,并在屏幕上连续渲染(因此形成视频)。 下面的功能是一种在屏幕上渲染每一帧的功能。
- (void)drawBufferWidth:(int)width height:(int)height pixels:(unsigned char*)pixels
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef gtx = CGBitmapContextCreate(pixels, width, height, BitsPerComponent, BytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colorSpace);
myimage = CGBitmapContextCreateImage(gtx); //myimage is of type CGImageRef
CGContextRelease(gtx);
img.image = [UIImage imageWithCGImage:myimage]; //img is of type UIImageView
[CATransaction flush];
CGImageRelease(myimage);
myimage = Nil;
}
该代码在模拟器上可以正常工作。 当我在设备上运行它时,它显示几帧,并显示“接收到内存警告”并崩溃。
我无法弄清楚问题出在哪里。 我是否没有正确分配内存,或者即使我释放映像,映像仍存在于内存中,从而耗尽了内存?
请帮助!
提前致谢。
编辑:
Xcode组织者说:
hevcd[665] has active assertions beyond permitted time:
{(
<SBProcessAssertion: 0x11aacf70> identifier: Suspending process: hevcd[665] permittedBackgroundDuration: 10.000000 reason: suspend owner pid:565 preventSuspend preventThrottleDownCPU preventThrottleDownUI
)}
一些观察:
假设您有一个for
循环:
for (i = start; i < end; i++) { // doing lots of memory intensive stuff }
您必须认识到,在该循环过程中自动释放的任何内存实际上都不会退还给操作系统,直到该循环完成并且刷新自动释放池为止。 理论上,当执行内存密集型操作时,您可以执行以下操作:
for (i = start; i < end; i++) { @autorelease { // doing lots of memory intensive stuff } }
这样,您可以手动创建一个新的自动释放池,该池将以更高的频率刷新。
话虽如此,您实际上不应该执行长时间的任务,这些任务不会退回到操作系统上(至少在主线程上,并且因为您正在执行UI事务,所以必须在主线程上执行此操作)。 与执行延长for
循环相比,更好的模型是让操作系统每隔一定的时间间隔调用代码。 然后,标准的自动释放池就可以完成工作,您应该会很好。 您可以这样创建一个计时器:
- (void)startTimer { self.timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(handleTimer:) userInfo:nil repeats:YES]; }
然后,您有一个例程来处理计时器:
- (void)handleTimer:(NSTimer *)timer { // do what you need here }
确保关闭计时器(例如,当视图消失时),否则关闭该视图控制器时,将不会释放它,因为计时器将保持对它的强烈引用,并且您将拥有一个保留周期(或强大的参考周期),您将泄漏内存。
- (void)viewWillDisappear:(BOOL)animated { [self.timer invalidate]; }
您也可以使用CADisplayLink
实现类似的功能。 您可以创建显示链接:
- (void)startDisplayLink { self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)]; [self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; } - (void)handleDisplayLink:(CADisplayLink *)displayLink { // do what you need here }
再次,您需要确保在完成后将其停止:
- (void)viewWillDisappear:(BOOL)animated { [self.displayLink invalidate]; }
所有这三种情况都可能会纠正您的内存状况(除非您有一些未检测到的保留周期或泄漏)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.