【问题标题】:observeValueForKeyPath not being called when returning to a UIViewController返回 UIViewController 时未调用 observeValueForKeyPath
【发布时间】:2017-06-21 02:03:33
【问题描述】:

我正在使用UIProgressView 跟踪进度,并为我正在跟踪的属性设置了一个观察者。

我在viewWillAppear中添加观察者,像这样:

-(void)viewWillAppear:(BOOL)animated
{
    [self addObserver:self forKeyPath:@"progress" options:0 context:nil];
}

当我在 viewWillDisappear 中移除观察者时,像这样:

-(void)viewWillDisappear:(BOOL)animated
{
    [self removeObserver:self forKeyPath:@"progress"];
}

在 observeValueForKeyPath 方法中我更新了进度视图:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object   change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
    if([keyPath isEqualToString:@"progress"])
    {

        [self.progressView setProgress:self.progress animated:YES];
    }
}

现在,当我离开 viewController 并返回时,observeValueForKeyPath 没有被调用,我也没有得到 progressView 的持续更新。

根据上面的代码,progressView 的行为如下视频所示: https://youtu.be/PVRT_Jjtdh4

【问题讨论】:

  • 您的代码似乎在自己观察您的viewController,其中不需要使用KVO。如果您不离开视图,这是预期的,您的进度视图将被更新。让人们感到困惑的是,在这种情况下,当你离开它的所有者时,你必须关心你的 progressView,因此离开 viewController。另一方面,如果你的progressView是viewController的外层视图,那么需要观察viewController的是progressView本身。

标签: ios objective-c key-value-observing uiprogressview viewwillappear


【解决方案1】:

键值编码 (KVC) 是一种间接访问对象属性的机制。在您的情况下,“进度”是UIProgressView 的属性。但是您已经为 UIViewController 对象注册了观察者,该对象没有“进度”作为属性。

因此将self 替换为self.progressView

[self addObserver:self.progressView forKeyPath:@"progress" options:0 context:nil];

进入

[self addObserver:self.progressView forKeyPath:@"progress" options:0 context:nil];

另外,对分离观察者做同样的事情:

[self removeObserver:self.progressView forKeyPath:@"progress"];

【讨论】:

  • 这不是问题。问题是当我离开视图并返回时,没有调用 observeValueForKeyPath 并且没有更新进度视图。但一切都很顺利,而我没有离开视野。
【解决方案2】:

通过示例查找更新的答案。这将对您有所帮助:

在这里,您必须在相对于接收器的关键路径上注册为值的观察者。您还需要设置选项。

使用:

-(void)viewWillAppear:(BOOL)animated
{
   [[Receiver Instance] addObserver:self forKeyPath:@"progress" options:NSKeyValueObservingOptionNew 
context:nil];
}

-(void)viewWillDisappear:(BOOL)animated
{
     [[Receiver Instance] removeObserver:self forKeyPath:@"progress"];
}   

休息就是这样。 这里,[Receiver instance] 是您定义的对象进度值正在变化的类的实例。

【讨论】:

  • 他们确实在那里
【解决方案3】:

最好只在类被释放后移除观察者。所以插入viewWillDisappear:animated: 你可以在下面做同样的事情:

-(void) dealloc {
      [self removeObserver:self forKeyPath:@"progress"]
      [super dealloc];
}

【讨论】:

    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    • 2016-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多