Swift给视频应用CIFilter时,销毁ViewController出现未完成请求释放错误
问题解决方案
核心问题分析
用[weak self]时,ViewController销毁后self变为nil,直接return会导致未完成的AVAsynchronousVideoCompositionRequest没有收尾,触发错误;去掉weak又会让AVMutableVideoComposition强引用ViewController,造成内存泄漏。
修复步骤
- 处理nil场景的请求收尾:当self为nil时,不要直接return,调用
request.finishCancelledRequest()告诉系统取消该请求,避免残留未完成任务。 - 保留弱引用避免泄漏:继续使用
[weak self]打破循环引用。 - ViewController销毁时清理资源:在
deinit中清空player的videoComposition,切断关联确保资源释放。
修改后的代码
var mutableComposition = AVMutableVideoComposition() let exposureFilter = CIFilter.exposureAdjust() override func viewDidLoad() { updateComposition() } func updateComposition() { mutableComposition = AVMutableVideoComposition(asset: player.currentItem!.asset, applyingCIFiltersWithHandler: { [weak self] request in guard let self = self else { // self已销毁,取消当前请求 request.finishCancelledRequest() return } self.exposureFilter.inputImage = request.sourceImage.clampedToExtent() self.exposureFilter.ev = 5 guard let output = self.exposureFilter.outputImage?.cropped(to: request.sourceImage.extent) else { // 滤镜处理失败,用错误收尾 request.finish(with: NSError(domain: "FilterError", code: -1, userInfo: [NSLocalizedDescriptionKey: "Failed to process image"])) return } request.finish(with: output, context: nil) }) player.currentItem?.videoComposition = mutableComposition } deinit { // 销毁时清空视频合成,切断关联 player.currentItem?.videoComposition = nil }
为什么这样有效
finishCancelledRequest()会正确收尾未完成的请求,消除控制台错误,同时避免后续预览变黑的问题。[weak self]确保ViewController可以被正常释放,解决内存泄漏。deinit里的清理操作能彻底切断player和videoComposition的关联,防止残留资源干扰后续编辑。
内容的提问来源于stack exchange,提问作者El Tecla
相关产品推荐
相关产品推荐

