AVPlayerViewController从画中画切回全屏后点击暂停崩溃求助
画中画切回全屏后点击暂停崩溃的原因分析及修复
崩溃原因分析
- 未调用系统要求的完成回调:
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler是AVKit强制要求必须触发的方法,你当前的代码完全没调用completionHandler,这会导致AVKit内部状态紊乱,后续的暂停操作会触发系统层面的异常崩溃。 - 重复present控制器:当当前可见控制器已经是
playerViewController时,你仍然执行present(playerViewController, animated: false),这会造成视图层级混乱,控制器生命周期被错误触发,点击暂停时因状态异常引发崩溃。 - player引用管理隐患:
playerViewControllerDidStopPictureInPicture仅获取player引用但未做任何状态同步处理,虽不直接导致本次崩溃,但如果player生命周期管理不当,后续操作可能出现野指针问题。
修复后的代码示例
func playerViewControllerDidStopPictureInPicture(_ playerViewController: AVPlayerViewController) { guard let player = self.moviePlayer?.player else { return } // 可在此添加PIP停止后的状态同步逻辑,比如更新播放UI } func playerViewController(_ playerViewController: AVPlayerViewController, restoreUserInterfaceForPictureInPictureStopWithCompletionHandler completionHandler: @escaping (Bool) -> Void) { let currentViewController = navigationController?.visibleViewController let restoreSuccess = true if currentViewController != playerViewController { currentViewController?.present(playerViewController, animated: true) { completionHandler(restoreSuccess) } } else { // 播放器已处于当前视图层级,直接告知系统恢复完成 completionHandler(restoreSuccess) } }
额外注意事项
- 确保
playerViewController实例仅被present一次,避免重复操作导致的视图层级冲突。 - 检查
moviePlayer和player的生命周期,在控制器销毁前正确置空引用,防止野指针崩溃。 - 测试时覆盖所有PIP切回场景,比如播放器处于导航栈push状态的情况(若你的场景是push而非present,需调整当前逻辑)。
内容的提问来源于stack exchange,提问作者newDev
相关产品推荐
相关产品推荐

