首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AVCam内存不足警告

AVCam内存不足警告
EN

Stack Overflow用户
提问于 2011-10-17 16:13:04
回答 3查看 2.1K关注 0票数 7

这不是一个问题,而是我在苹果为iOS4和5相机操作提供的AVCam示例代码周围找到的记录。对我来说,这个问题的症状是,我的应用程序在拍摄了大约5-10张照片后,在启动AVCamViewController时会崩溃。

我通过内存泄漏分析器运行了应用程序,没有明显的泄漏,但在使用Activity Monitor进行检查时,我发现每次启动摄像头时,名为mediaserverd的东西都会增加17Mb,当它达到~100Mb时,应用程序崩溃,并出现多个内存不足的警告。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-11-01 23:50:46

苹果在2013年10月17日修改了示例代码,修复了保留周期。该问题是由于在init中定义的块中不正确使用self造成的。

以下是修订说明

修复了AVCaptureManager中导致泄漏的保留周期。注意:如果你已经在你的应用中改编了AVCam代码,你应该采用AVCaptureManager.minit方法中这里所做的修复。如果没有这些修复,你可能会泄漏AVCaptureManager实例,并在你的应用处于前台时让摄像头持续运行。

然而,,他们介绍的修复只在手动保留计数的情况下有效。如果在项目中使用ARC,除了去掉release/retain调用和其他显而易见的东西之外,weakSelf的存储限定符必须从__block更改为__weak,如下所示。

代码语言:javascript
复制
__weak AVCamCaptureManager *weakSelf = self;

事实上,__block的语义随着ARC的变化而变化。在MRC中,它导致变量被弱引用,而在ARC中则不是,必须使用__weak来实现此目的。

有关此主题的更多信息可在此处找到:How do I avoid capturing self in blocks when implementing an API?

使用上一次修订中的新init实现,并使用__weak而不是__block,最终导致dealloc方法被正确调用。

最后,对于那些讨厌携带旧的遗留代码的人,这里有一个AVCam项目的现代版本:https://github.com/Gabro/AVCam

功能:

  • 内存泄漏免费
  • 使用ARC
  • 现代Objective-C语法
  • iOS 7

的次要UI修复<代码>F235

票数 4
EN

Stack Overflow用户

发布于 2011-10-25 09:45:38

我做的第一件事是将日志放入所有AVCam文件的dealloc方法中。我很快发现,当AVCamViewController被释放时,AVCamCaptureManager和AVCamRecorder并没有被释放。我检查了保留和释放调用,它们似乎是平衡的,所以我在captureManager版本上设置了一个断点,发现在发布之后它的retainCount为2(因此没有调用AVCamCaptureManager dealloc )。

接下来,我逐步完成了捕获管理器的创建过程,并发现在调用init方法后,它的保留计数立即为3。

单步执行init方法并检查每一行的保留计数,我发现以下两行都在递增保留计数:

代码语言:javascript
复制
[self setDeviceConnectedObserver=[notificationCenter addObserverForName:AVCaptureDeviceWasConnectedNotification object:nil queue:nil usingBlock:deviceConnectedBlock]];
[self setDeviceDisconnectedObserver=[notificationCenter addObserverForName:AVCaptureDeviceWasDisconnectedNotification object:nil queue:nil usingBlock:deviceDisconnectedBlock]];

通过查看,我发现removeObserver对等项位于AVCamCaptureManager的dealloc方法中(该方法未被调用),因此保留计数从未降为0。

为了解决这个问题,我创建了一个新的公共removeObservers方法:

代码语言:javascript
复制
 -(void)removeObservers {
     NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
     [notificationCenter removeObserver:[self deviceConnectedObserver]];
     [notificationCenter removeObserver:[self deviceConnectedObserver]];
 }

并从AVCamCaptureManager dealloc方法中删除相同的代码行。

调用captureManager % removeObservers;,然后调用captureManager dealloc方法中的% AVCamViewController release;,可成功将保留计数降为0。

使用活动监视器进行测试现在使mediaserverd进程仅以5-17Mb的速度嗡嗡作响,并且崩溃停止!

希望这篇文章能帮助其他有这个问题的人!

票数 16
EN

Stack Overflow用户

发布于 2013-07-19 10:53:00

最近遇到了这个问题。我发现真正的根本问题是deviceConnectedBlock和deviceDisconnectedBlock隐含地引用了self,导致了保留循环。要修复它,请将这些块中的所有ivar引用更改为使用weakSelf。

这样,您就不需要记得显式地调用teardown方法。

希望这对其他人有帮助。

参考:View controller dealloc not called when using NSNotificationCenter code block method with ARC

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7791002

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档