添加guard let self防护仍出现CMTime相关@escaping闭包thunk崩溃求助
崩溃根因
你代码中addPeriodicTimeObserver的回调闭包存在两处AVPlayer.currentItem强制解包操作,当播放状态异常(比如播放失败、快速切歌、播放器销毁时回调刚好触发、音频资源被系统回收)时,avPlayer.currentItem会变为nil,此时强制解包(!)会直接触发崩溃。
你本地无法复现是因为该崩溃属于时序偶现问题,只有回调触发和currentItem置空同时发生时才会出现,用户侧场景复杂更易触发。
修复方案
- 替换所有强制解包
currentItem的逻辑为可选绑定:
if (self.playStatus == .play) { // 先做可选绑定和有效性校验,完全避免强制解包 guard let currentItem = self.avPlayer.currentItem, !currentItem.duration.isIndefinite else { return } let duration = CMTimeGetSeconds(currentItem.duration) guard duration > 0 else { return } let progress = time.seconds / duration self.currentProgress = progress // 进度到20%统计逻辑 if progress >= 0.2 && self.isStatisticWhenTwenteen == true { self.isStatisticWhenTwenteen = false self.handleStatisticPlayProgress() } // 设置实际播放时间 PlayerFinishManager.shared.setupRealPlayRealTotalTime(seconds: Int(duration)) }
- 补充边界校验
- 移除浮点数直接判等逻辑
progress == 0.2,改为判断progress >= 0.2,避免回调时机偏差导致统计逻辑不触发。 - 在
PlayerManager销毁、切换播放资源的时机,必须调用avPlayer.removeTimeObserver(timeObserver)移除定时观察者,同时移除所有KVO、通知监听,避免野指针回调。
- 可选优化:注册和
currentItem绑定的通知、KVO时,切换currentItem要先移除旧item的监听,避免旧item的通知回调引发异常。
内容的提问来源于stack exchange,提问作者Dennie Lee
相关产品推荐
相关产品推荐

