1

我正在尝试制作一个播放多个视频的表格视图,AVPlayer并且AVPlayerItem我需要为每个视频添加观察者,AVPlayerItem以便我可以跟踪 playLikelyToKeepUp 属性

我尝试并失败的是在设置AVPlayerItem和删除它之后添加观察者deinitUITableViewCell但是由于单元格永远不会被释放但会被出队所以这不起作用,我会得到这个错误

An instance 0x14eedebc0 of class AVPlayerItem was 
deallocated while key value observers were still registered with it.

搜索后我想出了这个

  • 我不应该添加或删除观察者,UITableViewCell但我必须这样做,因为播放器项目是在单元子类中制作的
  • 处理观察者的最佳方式是在“UITableViewDelegate”方法中
  • 添加willDisplayCell和删​​除didEndDisplayingCell

但即使这在我的情况下也不起作用,因为AVPlayerItem需要时间来初始化

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! TableViewCell
        cell.setUpPLayer()
        return cell
}

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        let cell = cell as! TableViewCell
        if cell.Player == nil {
            self.addObserversToCell(cell)
        }
}

override func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
        let cell = cell as! TableViewCell
        self.removeMyObserversFromCell(cell)
}

所以观察者不会被添加,willDisplayCell但删除观察者将被调用,并会导致运行时错误

'Cannot remove an observer <AVFPlayer.TableViewCell 0x13cf1e9b0> for
the key path "playbackLikelyToKeepUp"  
<AVPlayerItem0x13cf31860> because it is not registered as an observer.'

如果有人知道如何做到这一点,我会很高兴知道?谢谢

4

2 回答 2

3

所以对我来说最好的解决方案是子类化AVPlayerItem并使用协议委托回任何符合的类AMPlayerItemDelegate

我是这样做的

protocol AMPlayerItemDelegate {
    func playbackLikelyToKeepUp()
}

class AMPlayerItem: AVPlayerItem {

   var delegate : MyPlayerItemDelegate?

   init(URL: NSURL) {
       super.init(asset: AVAsset(URL: URL) , automaticallyLoadedAssetKeys:[])
       self.addMyObservers()
   }

   deinit {
       self.removeMyObservers()
   }

   func addMyObservers() {
       print("Adding")
       self.addObserver(self, forKeyPath: "playbackLikelyToKeepUp", options: [.New], context: nil)
   }

   func removeMyObservers() {
       print("Removing")
       self.removeObserver(self, forKeyPath: "playbackLikelyToKeepUp", context: nil)
   }

   override func observeValueForKeyPath(keyPath: String?, ofObject object: AnyObject?, change: [String : AnyObject]?, context: UnsafeMutablePointer<Void>) {
       if keyPath == "playbackLikelyToKeepUp" {
           self.delegate?.playbackLikelyToKeepUp()
       }
   }

}
于 2016-04-15T12:59:20.890 回答
0

尝试覆盖 UITableViewCell 子类中的“prepareForReuse”函数,并在该位置删除观察者。

override func prepareForReuse() {
    super.prepareForReuse()

    //remove observer here...
}
于 2016-04-14T22:13:59.217 回答