【问题标题】:Send NSNotification in observeValueForKeyPath在 observeValueForKeyPath 中发送 NSNotification
【发布时间】:2017-02-28 00:08:38
【问题描述】:

我有一个AVPlayer 和一个速率观察员。

[self.player addObserver:self
                          forKeyPath:@"rate"
                             options:NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew
                             context:&RateContext];

在我的observeValueForKeyPath 方法中,我尝试发送通知让playerLayer superView 知道播放器何时开始/停止。

- (void)observeValueForKeyPath:(NSString *)keyPath
                  ofObject:(id)object
                    change:(NSDictionary<NSString *,id> *)change
                   context:(void *)context {

    if ([keyPath isEqualToString:@"rate"]) {
        if (self.player.rate == 0) {
            [self.indicatorView startAnimating];
            dispatch_async(dispatch_get_main_queue(), ^{
                 [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStopped" object:nil];
             });
            [self videoStalled];
        }else if (self.player.rate == 1){
            [self.indicatorView stopAnimating];
          //dispatch_async(dispatch_get_main_queue(), ^{
          //   [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStarted" object:nil userInfo:dic];
          //});
        }
        return;
    }

在我的videoStalled 中,我等到更多视频加载完毕,然后致电[self.player play]。然后调用“Rate”,只有当我注释掉通知帖子时,视频才会立即播放。当我取消注释通知时,仍会调用“Rate”,但播放器直到几秒钟后才会播放。不知道大滞后来自哪里。

【问题讨论】:

  • 延迟是从调度到您正在执行的主 UI 线程。您不需要实际分派到 UI 线程来发布通知。此外,如果您不在主 (UI) 线程上,调用 [self.indicatorView stopAnimating] 应该会使应用程序崩溃

标签: ios avplayer key-value-observing kvocontroller


【解决方案1】:

使用几个 NSLog 调用来显示流程的去向和花费的时间。

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary<NSString *,id> *)change
                       context:(void *)context {

    if ([keyPath isEqualToString:@"rate"]) {
        if (self.player.rate == 0) {
            [self.indicatorView startAnimating];
            [self videoStalled];
            NSLog(@"stage 1");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStopped" object:nil];
        }else if (self.player.rate == 1){
            [self.indicatorView stopAnimating];
            //dispatch_async(dispatch_get_main_queue(), ^{
            //   [[NSNotificationCenter defaultCenter] postNotificationName:@"playerStarted" object:nil userInfo:dic];
            //});
        }
        return;
    }
}

- (void) playerStopped
{
    NSLog(@"stage 2");
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"stage 3");
        [self.player play];
    });
}

这样你就可以看到它是否是一个让事情变慢的线程。您也可以只使用另一个观察者而不是通知来触发对 playStopped 方法的调用。我发现通知最适合在时间紧迫的情况下使用。

【讨论】:

    猜你喜欢
    • 2023-03-19
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多