音频队列和 EXC_BAD_ACCESS

Posted

技术标签:

【中文标题】音频队列和 EXC_BAD_ACCESS【英文标题】:Audio queue and EXC_BAD_ACCESS 【发布时间】:2012-01-17 08:40:48 【问题描述】:

这是我使用音频队列生成噪音的代码:

http://pastebin.com/Kn8GU72J

问题是我的代码生成了一个 EXC_BAD_ACCESS。问题似乎出在作业中

    MAAudioManager *audioMngr = (__bridge MAAudioManager *) inUserData;

在回调例程中。 我怀疑这可能与 MAAudioManager 类的线程访问有关。

有什么想法吗?

【问题讨论】:

【参考方案1】:

程序中是否有任何其他地方保留了MAAudioManager 实例?看起来在回调被调用时它已经被释放了。

【讨论】:

你是对的。没有 ARC 的相同程序运行良好。似乎 ARC 释放了 MAAudioManager 实例。好的,我需要学习更好的ARC。同时,关于如何避免 ARC 释放对象的任何想法?谢谢! 您需要在某处保留指向 MAAudioManager 实例的指针。例如,您可以将其保存在创建它的对象的实例变量或应用委托中。 使用 NSZombie 进行调试也是一个好主意,您可以在“Scheme”对话框中执行此操作,该选项称为“启用僵尸对象”。启用该功能后,您将获得更多信息,而不仅仅是 EXC_BAD_ACCESS。 实际上在应用代理中已经有了MAAudioManager *audio = [[MAAudioManager alloc] init];。可能我错过了什么。 这是一个局部变量。一旦方法结束,变量就会超出范围,并被删除。这就是 ARC 释放您的对象的原因。您需要将audio 声明为实例变量,这意味着在您的应用程序委托@interface 部分(在头文件中)中声明它,如MAAudioManager *audio。只要对象存在,在那里声明的变量就会一直存在,对于应用程序委托来说,这就是应用程序的生命周期。然后,您可以将您发布的行替换为audio = [[MAAudioManager alloc] init]

以上是关于音频队列和 EXC_BAD_ACCESS的主要内容,如果未能解决你的问题,请参考以下文章

使用 libmms 和音频队列

音频队列和 EXC_BAD_ACCESS

“音频队列服务”的好指南?

音频队列服务录制到 .mp4 文件,无法播放。和魔术饼干问题

AudioQueueStop 后音频队列无法重新启动

使用音频队列框架录制的数据格式