【问题标题】:App Crash, "Lost Connection"应用程序崩溃,“失去连接”
【发布时间】:2018-01-28 09:01:42
【问题描述】:

类似于这个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)
    }
}

它会打印“done”,但从不打印“removing AI”。它也不打印“cool”或“(error)”;正如另一个问题所述,它崩溃并在 XCode 顶部显示“丢失与 iPhone 的连接......”。

我认为这是一个内存问题,但在异步导出期间(据我所知这是如何工作的)之间没有发生任何事情,因为我只是在等待调用完成处理程序。但是中间没有任何东西被调用,我不确定如何处理这个问题。有什么想法吗?

【问题讨论】:

  • 试着放try,catch块,然后贴出crash的堆栈信息?
  • 嗯。如果你参考了上面的帖子,你会发现没有办法抓住它。它只是崩溃并说它无法连接到设备。应用程序崩溃。没有日志,它没有向我显示“问题”。这就是为什么我从另一篇文章中假设它可能是记忆。
  • 为了能够更好地帮助您,我建议您创建重现问题的最小代码,以便我们也可以对其进行测试。此外,我建议一种启发式方法,即:删除一些代码块,看看它是否失败......如果没有,则将那部分放回原处并删除代码的另一部分或更多部分,直到它不崩溃.然后您也许能够确定问题的根源
  • 这听起来不错,但崩溃并非每次都发生。很难测试这样的能力。
  • 我使用 Instruments 中的内存分配模板解决了一个类似的问题,以查找哪个方法分配了大量内存。即使不是每次都崩溃,它也可以帮助您找出问题所在。

标签: ios swift xcode avassetexportsession


【解决方案1】:

我认为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 不存储在可能会释放它的方法上。可能是内存问题造成的。

【讨论】:

  • 您认为这会完全导致崩溃,正如另一个问题中所讨论的那样?我认为这可能会导致某些东西为零的问题。在完成块中,我对 UI 做了很多工作,因此我需要主线程。这就是大多数完成块所具有的(根据我的经验)
  • 是的,我愿意,试试看。主线程没问题,但是在 func 之外存储对象以防止在异步线程上运行任务时释放。以 CoreLocation 为例,当您创建可以对信标进行测距的内部 func 对象并尝试对其强制测距时,这将导致对象解除分配,最终不会返回任何值。
  • 是的,之前处理过这个问题。但是当我使用 CoreLocation 时,它提供了一个错误,并说找不到崩溃日志。这只是显示“设备与 XCode 断开连接”
  • 这将取决于它是如何在框架内部实现的。仅仅因为 CoreLocation 产生“适当的崩溃”并不意味着它不是同一个问题。您在问题中的代码 sn-p 实际上并没有显示如何/如果您将导出器存储在某处,但从我所见,它看起来像您定义的范围,它在完成时可能不再有效。我已经看到这会导致在调试时失去与手机的连接。此外,在实现 Kuba 的解决方案时,请确保类实例不会过早地被释放(这将是同样的问题)。
  • 是的,为了测试这是否是一个问题,您甚至可以将myClass 作为变量存储在AppDelegate 中,以确保它不会被释放,但如果这解决了问题,请移动它: D
【解决方案2】:

我以前遇到过这个问题,对我来说不是内存问题。我不知道我到底是如何解决的,但我就是这样做的:

我删除了应用程序,硬重置手机,清理了 Xcode 上的构建,重新启动了 Xcode,删除了派生数据,如果我没记错的话,我还更改了 USB 端口,直到它得到修复。

我还打开了控制台和虚拟机,我也关闭了它们。

【讨论】:

  • 这发生在通过计算机进行试飞/运行时以及在包括模拟器和测试人员的手机在内的多种设备上。
  • @impression7vx 哦。诡异的。请将该信息添加到您的问题中,因为我认为这仅发生在设备上。但我不知道了
  • 我做到了,当我说“类似于这个问题”时,另一个问题立即指出“我的应用程序崩溃了,我需要一些建议来查找和解决问题。这不是设备或电缆问题因为它发生在所有设备上,而不仅仅是在调试时”。我完全没有必要根据自己的情况重述这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 2011-12-19
  • 1970-01-01
  • 2017-11-03
相关资源
最近更新 更多