在 UITableViewCell 的多个 AVPlayerItem 中添加和删除观察者
Add and remove observer from multiple AVPlayerItem on UITableViewCell
我正在尝试制作一个 table 视图来播放多个带有 AVPlayer
和 AVPlayerItem
的视频,我需要为每个 AVPlayerItem
添加 Observer 以便我可以跟踪播放的 LikelyToKeepUp 属性
我尝试但失败的是在设置 AVPlayerItem
并在 UITableViewCell
的 deinit
中删除它之后添加观察者,但是由于单元格永远不会被释放但会被出队所以这行不通,我会得到这个错误
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.'
如果有人知道如何实现这一点,我很乐意知道?谢谢
尝试覆盖 UITableViewCell 子类中的 'prepareForReuse' 函数,并在那个地方删除观察者。
override func prepareForReuse() {
super.prepareForReuse()
//remove observer here...
}
所以对我有用的最佳解决方案是 class AVPlayerItem
并使用协议委托回任何符合 AMPlayerItemDelegate
[的 class
我是这样做的
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()
}
}
}
我正在尝试制作一个 table 视图来播放多个带有 AVPlayer
和 AVPlayerItem
的视频,我需要为每个 AVPlayerItem
添加 Observer 以便我可以跟踪播放的 LikelyToKeepUp 属性
我尝试但失败的是在设置 AVPlayerItem
并在 UITableViewCell
的 deinit
中删除它之后添加观察者,但是由于单元格永远不会被释放但会被出队所以这行不通,我会得到这个错误
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.'
如果有人知道如何实现这一点,我很乐意知道?谢谢
尝试覆盖 UITableViewCell 子类中的 'prepareForReuse' 函数,并在那个地方删除观察者。
override func prepareForReuse() {
super.prepareForReuse()
//remove observer here...
}
所以对我有用的最佳解决方案是 class AVPlayerItem
并使用协议委托回任何符合 AMPlayerItemDelegate
[的 class
我是这样做的
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()
}
}
}