KVO增加移除问题

关于kvo的使用不是本文的讨论范围,本文主要讲一下业务复杂的情况下,kvo的observer管理[add/remove]。 ####使用场景 一个AVQueuePayer的播放器,面对多个AVPlayerItem,对于currentItem一些属性的监视,如何做了,且看看我的方案吧。

规则:在这样一个Queue中有能播放的,有失败的,若一个Item失败,播放下一个,只到最后一个Item终止。
1.[player advancetoNextItem]之前移除currentItem的observer,之后增加currentItem的observer

[self removeCurrentPlayerItemObserver:self.player.currentItem];
[player advancetoNextItem];
[self addCurrentPlayerItemObserver:self.player.currentItem];

- (void)addCurrentPlayerItemObserver:(AVPlayerItem *)playerItem {
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)removeCurrentPlayerItemObserver:(AVPlayerItem *)playerItem {
    [playerItem removeObserver:self forKeyPath:@"status"];
    [playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
    [playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}
复制代码

上述的代码且不说严谨什么问题,对于observer的add/remove请按照成对调用,多了崩溃,少了也会崩溃。而这儿对于currentItem的的observer add/remove时,时机在播放流程正常的情况下是一番风顺,对于网络不好,播放地址服务器导致失败的,会出现当前item的observer移除失败。故有了下面的方案

增加
对于增加了observer的AVPlayerItem把他塞到这样一个数组里面
1.数组里若有则不再add observer

移除observer
对于AVPQueuePlayer我们只要保证currentItem有observer就好,所以移除时,我们直接对整个数组实例的observer移除。

复制代码

show me code


/** 调用这两个方法即可*/
- (void)addPlayerItemObserver:(nonnull AVPlayerItem *)playerItem;
- (void)removePlayerItemsObser;

- (void)addCurrentPlayerItemObserver:(nonnull AVPlayerItem *)playerItem;
- (void)removeCurrentPlayerItemObserver:(nonnull AVPlayerItem *)playerItem;

复制代码
- (void)addPlayerItemObserver:(nonnull AVPlayerItem *)playerItem {
    if(playerItem == nil) {
        return;
    }
    NSInteger index = -1;
    for(AVPlayerItem * tmPlayerItem in self.addObserverPlayerItems) {
        if(tmPlayerItem == playerItem) {
            index = 0;
            break;
        }
    }
    if(index < 0) {
        [self  addCurrentPlayerItemObserver:playerItem];
        [self.addObserverPlayerItems addObject:playerItem];
    }
}
- (void)removePlayerItemsObser {
    for(AVPlayerItem * playerItem in self.addObserverPlayerItems) {
        [self removeCurrentPlayerItemObserver:playerItem];
    }
    [self.addObserverPlayerItems removeAllObjects];
}
- (void)addCurrentPlayerItemObserver:(AVPlayerItem *)playerItem {
    [playerItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"playbackBufferEmpty" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"playbackLikelyToKeepUp" options:NSKeyValueObservingOptionNew context:nil];
    [playerItem addObserver:self forKeyPath:@"loadedTimeRanges" options:NSKeyValueObservingOptionNew context:nil];
}

- (void)removeCurrentPlayerItemObserver:(AVPlayerItem *)playerItem {
    [playerItem removeObserver:self forKeyPath:@"status"];
    [playerItem removeObserver:self forKeyPath:@"playbackBufferEmpty"];
    [playerItem removeObserver:self forKeyPath:@"playbackLikelyToKeepUp"];
    [playerItem removeObserver:self forKeyPath:@"loadedTimeRanges"];
}
复制代码

注:时光不老,陪伴我们的最终是什么,存在的意义又是如何,愿留下些许感动,还好有你~ (胡言乱语)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值