iOS 实现音频流播放器中踩的内存管理相关的坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fly1183989782/article/details/81205583

    App 作为工具应用,具备语音提醒的能力。语音是调用云服务进行合成的,这样做灵活些,新增提醒不用准备相应的语音文件。云服务合成音频,以流的方式返回到端上,端上使用 Audio Queue 播放。流式播放,可以抽象为生产者-消费者问题。云是我们的生产者,麦克风是我们的消费者。Audio Queue 已经把问题解决一半了,它创建了 Buffer,提供钩子告诉我们Buffer可用,提供接口让我们调用来告诉它“Buffer我们填满了”。生产者-消费者问题需要协调生产者、消费者对缓存的访问。经典解决方案是利用信号量。有了 GCD,我的用队列来实现的。生产出音频数据时,如果有 Buffer,填充 Buffer,Flush;否则将音频文件加入 producerBuffer,再次缓冲。麦克风消费了音频文件,空出了 Buffer,如果 producerBuffer 当中有数据,填充 Buffer,Flush;否则将 Buffer 放到可用 Buffer 列表(consumerBuffer)当中。这里 producerBuffer,consumerBuffer 都可能在不同的线程被修改,需要保证线程安全,我的做法是对修改操作都加入队列中进行串行,也可以用锁,或者无锁的机制类似 compareAndSwap。我遇到的内存问题是说我的 player 会被外部 retain,被内部 block retain,被 CoreFoundataion Audio Queue retain,在加上异步的问题,偶现需要访问时已经被回收的情况,SIGABRT、BAD_ACCESS 都出现了。主要原因是被 Audio Queue retain 的平衡操作不对,即调用 CFRelease 太早。在 BufferCallback 再次被调用的时候, player 已经 deallco。

猜你喜欢

转载自blog.csdn.net/fly1183989782/article/details/81205583