使用AVPlayer播放在线音频流时出现内存泄漏问题
播客应用AVPlayer内存泄漏问题排查与解决
问题描述
开发播客播放应用时,通过URL或AVPlayerItem创建AVPlayer会出现内存泄漏,但对象的deinit方法可正常执行且无异常。相关代码如下:
weak var presenter: AudioPlayerUpdaterProtocol? private var audioSession: AVAudioSession? private var audioPlayer: AVPlayer? private var audioURL: URL? private var playbackTimeUpdater: Timer? deinit { self.audioSession = nil self.audioURL = nil self.audioPlayer = nil self.playbackTimeUpdater?.invalidate() removeEndPlayingObserver() print("deinit audio") } private func setupAudioPlayer(){ guard let url = audioURL else { return } let playerItem = AVPlayerItem(url: url) // 注释掉AVPlayer初始化时无内存泄漏 audioPlayer = AVPlayer(playerItem: playerItem) addEndPlayingObserver() startPlaying() }
使用Instruments调试发现存在16字节的malloc内存泄漏,但在Xcode内存图中无法找到对应泄漏对象。
排查与解决建议
确保观察者完全移除:检查
addEndPlayingObserver方法中,是否给AVPlayer或AVPlayerItem添加了KVO通知(如status、playbackBufferEmpty等),必须在removeEndPlayingObserver里彻底移除所有关联的观察者,遗漏的KVO会导致内存残留。主动释放AVPlayerItem资源:在销毁AVPlayer前,先清空其持有的playerItem,再置空AVPlayer。修改
deinit方法:
deinit { // 先清空playerItem,释放关联资源 audioPlayer?.replaceCurrentItem(with: nil) audioPlayer = nil playbackTimeUpdater?.invalidate() playbackTimeUpdater = nil removeEndPlayingObserver() // 停用并清理音频会话 do { try audioSession?.setActive(false, options: .notifyOthersOnDeactivation) } catch { print("音频会话停用失败: \(error)") } audioSession = nil audioURL = nil print("deinit audio") }
彻底清理Timer:调用
invalidate后必须将Timer实例置为nil,避免因Timer的弱引用残留导致微小泄漏。排查系统框架已知问题:部分iOS版本中AVPlayer存在已知的微小内存泄漏(如你遇到的16字节),如果上述操作后泄漏仍存在且量级极小、不影响应用稳定性,可判定为系统层面问题,无需过度关注。
内容的提问来源于stack exchange,提问作者Mohamed Mostafa
相关产品推荐
相关产品推荐

