Add and remove observer from multiple AVPlayerItem on UITableViewCell

十年热恋 提交于 2019-12-01 12:02:34

问题


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

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.

After searching I came up with this

  • 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

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

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


回答1:


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

here is how i did it

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:


Try to override 'prepareForReuse' function in your UITableViewCell subclass, and remove observer in that place.

override func prepareForReuse() {
    super.prepareForReuse()

    //remove observer here...
}


来源:https://stackoverflow.com/questions/36632104/add-and-remove-observer-from-multiple-avplayeritem-on-uitableviewcell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!