在UITableViewCell上添加和删除多个AVPlayerItem的观察者 [英] Add and remove observer from multiple AVPlayerItem on UITableViewCell

查看:408
本文介绍了在UITableViewCell上添加和删除多个AVPlayerItem的观察者的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个能够以 AVPlayer AVPlayerItem 播放多个视频的桌面视图,并且我需要addObserver到每个 AVPlayerItem 所以我可以跟踪playbackLikelyToKeepUp属性

i am trying to make a table view that plays multiple videos with AVPlayer and AVPlayerItem and i needed to addObserver to each AVPlayerItem so i can keep track of playbackLikelyToKeepUp property

我尝试过但失败的是在设置后添加观察者 AVPlayerItem 并将其删除在 UITableViewCell deinit 中但由于单元格永远不会被释放但是会出列,所以这不会起作用,我会得到这个错误

what i tried and failed is adding the observer after setting the AVPlayerItem and removing it in the deinit of the UITableViewCell but since the cells never gets deallocated but gets dequeued so this won't work and i will get this error

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

搜索后我想出了这个


  • 我不应该在 UITableViewCell 上添加或删除观察者,但我不得不因为播放器项是在单元子类中生成的

  • 处理观察者的最佳方法是在'UITableViewDelegate'方法中

  • 添加 willDisplayCell 并删除 didEndDisplayingCell

  • I should not add or remove observers on UITableViewCell but i had to because the player item is made in the cell subclass
  • The best way to handle observer is within 'UITableViewDelegate' methods
  • Adding in willDisplayCell and removing in didEndDisplayingCell

但即使这样也无法解决,因为 AVPlayerItem 需要时间进行初始化

but even that does not work in my case because AVPlayerItem takes time to be initialized

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 但是会删除观察者,并且会导致运行时错误

so the observer won't be add in the willDisplayCell but removing the observer will be called and will cause runtime error with

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

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

if anyone knows how to achieve this , I would be happy to know ? thanks

推荐答案

因此,对我有用的最佳解决方案是继承 AVPlayerItem 并使用协议委托回任何类符合 AMPlayerItemDelegate

So the best solution that ever worked for me is to subclass the AVPlayerItem and use protocol to delegate back to any class that conforms to 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()
       }
   }

}

这篇关于在UITableViewCell上添加和删除多个AVPlayerItem的观察者的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆