3

我使用 ARC 构建了一个相当简单的应用程序。但是,我遇到了内存不足,但我不知道是什么原因造成的。由于我无法澄清是什么原因造成的,因此我有一些具体的细节和问题。

当我尝试加载新的视图控制器时,问题就出现了。AVAudioPlayer这个视图控制器承载了许多图像,并且在加载时会在我拥有的单例类中添加一个 3-4 分钟的音频文件。

当视图控制器被推送和弹出 8-10 次时会出现问题。当视图控制器弹出时,我调用stop并将AVAudioPlayer所有相关对象(包括AVAudioPlayer实例)返回为零。

我真的不明白是什么导致了内存泄漏,或者还有什么可能会破坏设备内存,但我确实有一些具体的问题。

停止时AVAudioPlayer,是否仍允许在内存中适当释放?

AVAudioPlayer调用后将指针设置为 nil 会stop阻止系统从设备内存中释放某些数据吗?

在 ARC 中,当所有者被释放时不应该释放任何东西(我问的是我的所有视图和数据UIViewController都从堆栈中弹出)吗?

我应该知道 ARCAVFoundation或ARC 中有什么问题吗?AVAudioPlayer

是否stop以错误的方式结束音频会话/是否已将其释放?

编辑:我已经开始使用工具工具来跟踪我的分配和泄漏。没有任何内存泄漏,或者工具说,但应用程序会崩溃,几乎不管活动字节。当使用的总 RAM 超过 200MB(210-230MB - 我的设备有 256MB 的 RAM)时,应用程序将崩溃。我的新问题是分配的总字节数(即使它们不存在)会影响内存崩溃吗?如果是这样,我该如何防止这种情况?

是崩溃的运行图像。你可以在最后看到一堆内存警告。

4

2 回答 2

5

Q) 当视图控制器被推送和弹出 8-10 次时会出现问题。当视图控制器弹出时,我在 AVAudioPlayer 上调用 stop 并将所有相关对象(包括 AVAudioPlayer 实例)返回为零。A)添加一个dealloc方法并记录dealloc,所以你知道没有保留那些,然后在控制台中查找这些:

- (void)dealloc
{
  NSLog(@"MySpecialViewController getting dealloced!");
}

如果你没有看到这些东西正在保留这个对象 - 可能是一个委托。

问)我真的不明白是什么导致了内存泄漏,或者还有什么可能会破坏设备内存,但我确实有一些具体的问题。A)您应该在 Instruments(和 Leaks)中使用 ObjectAlloc。这些非常易于使用 - 在模拟器中使用它们运行项目,只需使用默认值,您就会立即获得很多有用的信息。您可以看到 WHAT 正在泄漏,这应该会有所帮助。

Q) 停止 AVAudioPlayer 时,是否仍允许在内存中正确释放?A)不。你必须将你的强 ivar/属性设置为 nil (你说你正在这样做)。我刚刚检查过,AVAudioPlayer 没有保留委托。也就是说,作为一般规则,当我关闭任何东西时:

[something stop/cancel/etc]; 
something.delegate = nil; 
something = nil;

调用 stop 后将 AVAudioPlayer 指针设置为 nil 会阻止系统从设备内存中释放某些数据吗?

Q) 在 ARC 中,当所有者被释放时不应该释放任何东西(我问的是我的 UIViewController 中的所有视图和数据从堆栈中弹出)吗?A)如果唯一保留 ViewController 的东西,例如 navigationController 的 viewControllers 数组,那么是的,你的 viewController 子类应该被释放,所有强属性和 ivars 也将被释放。

Q) 我应该知道 ARC 中的 AVFoundation 或 AVAudioPlayer 有什么问题吗?A)我不知道,因为这是一个受欢迎的课程,所以您的问题出在您的代码中。

Q) 调用 stop 是否是结束音频会话的错误方式/是否已将其释放?A)如果是我:

[avPlayer stop];
avPlayer.delegate = nil;
avPlayer = nil;

编辑:如果您在应用程序运行时收到内存警告,则说明您正在泄漏或消耗大量内存。在收到此警告的位置设置断点,停止应用程序并查看分配情况。我从来没有真正收到过内存警告(我只使用 ARC)

于 2012-09-03T20:01:36.423 回答
0

使用 ARC 时很容易遇到内存问题的一个领域是,您正在与需要来自后台线程的主线程的 Cocoa Touch API 进行交互。

听起来您并不反对这一点,但是如果您开始看到不一致的行为(例如,似乎是随机崩溃、对象过早超出范围等),那么值得投入一些精力来查看您是否正在交互来自后台线程的 Cocoa Touch。

有时来自 Cocoa Touch 的回调(可能会假设在主线程上)不是(我们在一些 Game Center API 中看到了这一点)。

于 2012-09-03T21:17:29.267 回答