与此this question类似,
我遇到问题,我的应用程序也以同样的方式崩溃。我会假设与另一个问题相同的答案:记忆问题;除了我在AVAssetExportSession调用期间遇到崩溃。
guard let exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) else { return }
exporter.outputFileType = AVFileTypeMPEG4
exporter.outputURL = url
exporter.videoComposition = mainComposition
print("done")
exporter.exportAsynchronously(completionHandler: {
DispatchQueue.main.async(execute: {
self.exportDidFinish(exporter)
print("removing AI")
self.removeAI()
print("removed AI")
completion()
})
})
func exportDidFinish(_ exporter:AVAssetExportSession) {
if(exporter.status == AVAssetExportSessionStatus.completed) {
print("cool")
}
else if(exporter.status == AVAssetExportSessionStatus.failed) {
print(exporter.error as Any)
}
}
它打印“完成”但它从不打印“删除AI”。它也不打印“酷”或“(错误)”;它崩溃并在XCode的顶部说“失去与iPhone的连接......”就像另一个问题所说的那样。
我认为这是一个内存问题,但在异步导出期间(我对其工作原理的知识)之间没有任何事情发生,因为我只是在等待调用完成处理程序。但是之间没有任何东西被调用,我不确定如何处理这个问题。有什么想法吗?
答案 0 :(得分:4)
我认为在运行异步任务时可能会释放AVAssetExportSession
对象。考虑将其作为类变量,以确保异步块可以完成它的任务。它将类似于:
class myClass {
var exporter: AVAssetExportSession?
func export() {
exporter = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)
guard exporter != nil else { return }
exporter.outputFileType = AVFileTypeMPEG4
exporter.outputURL = url
exporter.videoComposition = mainComposition
print("done")
exporter?.exportAsynchronously(completionHandler: {
DispatchQueue.main.async {
self.exportDidFinish(exporter)
print("removing AI")
self.removeAI()
print("removed AI")
completion()
}
}
}
}
我真的不确定为什么你也把所有东西放在完成块的主线程上,但也许你想稍后用UI做一些事情,所以我把它放在那里。
但最重要的是 - 让你的AVAssetExportSession
没有存储在可能解除它的方法上。这是一个可能导致这种情况的记忆问题。
答案 1 :(得分:3)
之前我遇到过这个问题,对我来说这不是一个记忆问题。我不知道我究竟是如何解决的,但我这就是我所做的事情:
我删除了应用程序,硬重置手机,清理了Xcode上的构建,重新启动了Xcode,删除了派生数据,如果我记得正确更改了USB端口,直到它被修复。
我也打开了控制台和VM,我也关闭了它们。