我是从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)>
这不应该发生,因为assetTrack
上AVPlayerItemTrack
的类型是var assetTrack: AVAssetTrack { get }
。但显然这不是真的。
(所有视频处理都在主线程上完成)
答案 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似乎在这方面有严重的退步。