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

iOS11 crashes on AVPlayerItemTrack.assetTrack.mediaType (Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

我正在键值观察来自 AVPlayerItem 的曲目 属性,如下所示:

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)>

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

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

这里的神话是,编程时 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 似乎在这方面有严重的倒退。