【问题标题】:Add and remove observer from multiple AVPlayerItem on UITableViewCell从 UITableViewCell 上的多个 AVPlayerItem 添加和删除观察者
【发布时间】:2016-04-14 19:20:49
【问题描述】:

我正在尝试制作一个表格视图,它可以使用AVPlayerAVPlayerItem 播放多个视频,并且我需要将Observer 添加到每个AVPlayerItem 以便我可以跟踪playbackLikelyToKeepUp 属性

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

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.'

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

【问题讨论】:

  • 子类化AVPlayerItem 并在其中添加/删除观察者呢?
  • 看起来很有趣,我试试看
  • Awesome 效果很好,非常感谢:D

标签: ios swift avfoundation avplayerlayer avplayeritem


【解决方案1】:

所以对我来说最好的解决方案是继承 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()
       }
   }

}

【讨论】:

    【解决方案2】:

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

    override func prepareForReuse() {
        super.prepareForReuse()
    
        //remove observer here...
    }
    

    【讨论】:

    • 是的,但这意味着观察者会一直徘徊,直到单元格准备好重新使用。如果有大量单元格,这可能是个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-03
    相关资源
    最近更新 更多