iOS11在AVPlayerItemTrack.assetTrack.mediaType上崩溃(线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x0)

时间:2017-09-28 15:11:31

标签: ios swift xcode ios11

我是从AVPlayerItem观察track属性的键值,如下所示:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if context == &PlayerItemObserverContext {
        [... more code...]
        } else if keyPath == #keyPath(AVPlayerItem.tracks) {
            if let playerItem = self.playerItem {
                for track in playerItem.tracks where track.assetTrack.mediaType == AVMediaType.video {
                    // Do something with the track
                    break
                }
            }
        } [... more code...]

但是当快速跳过我的应用程序时崩溃

for track in playerItem.tracks where track.assetTrack.mediaType == AVMediaType.video {

XCode 9调试器显示Thread 1: EXC_BAD_ACCESS (code=1, address=0x0

我可以清楚地看到track.assetTrack是零!

(lldb) po track.assetTrack
 <uninitialized>
(lldb) po track
<AVPlayerItemTrack: 0x1c80083b0, assetTrack = (null)>

这不应该发生,因为assetTrackAVPlayerItemTrack的类型是var assetTrack: AVAssetTrack { get }。但显然这不是真的。

(所有视频处理都在主线程上完成)

1 个答案:

答案 0 :(得分:3)

这里的神话是,在编写Swift(本例中为4)时,您处于安全的环境中。我学到的很难的方法是语言可能是安全的,但运行时不是。

(希望是临时的)解决方法是执行以下操作:

for track in playerItem.tracks where track.assetTrack != nil && track.assetTrack.mediaType == AVMediaType.video {

即使编译器认为这是愚蠢的,因为XCode抱怨:

Comparing non-optional value of type 'AVAssetTrack' to nil always returns true

但它确实可以解决问题,应用程序不再崩溃了!

代码在iOS10和之前的版本中没有修复,但iOS11似乎在这方面有严重的退步。