显示 DetailViewController 时在哪里为 KVO 添加和删除观察者

Posted

技术标签:

【中文标题】显示 DetailViewController 时在哪里为 KVO 添加和删除观察者【英文标题】:Where to add and remove observers for KVO when presenting a DetailViewController 【发布时间】:2012-05-30 03:06:32 【问题描述】:

我有一个带有标注的 MKMapView。按下标注(详细信息披露指示器)按钮时,它会显示一个 detailViewController。我想为我的注释添加更改地图类型和图钉颜色的功能。所以我目前这样做:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control 

    DetailMapViewController *destination = [[DetailMapViewController alloc] initWithNibName:@"DetailMapViewController" bundle:nil];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:destination];

    if ([destination  respondsToSelector:@selector(setDelegate:)]) 
        [destination setValue:self forKey:@"delegate"];
    
    if ([destination respondsToSelector:@selector(setPlacemark:)]) 
        [destination setValue:_currentPlacemark forKey:@"Placemark"];
    
    if ([destination respondsToSelector:@selector(setMapTypeAsNum:)]) 
        [destination setValue:[NSNumber numberWithInteger:self.mapView.mapType] forKey:@"mapTypeAsNum"];

        [destination addObserver:self forKeyPath:@"mapTypeAsNum" options:NSKeyValueObservingOptionNew context:NULL];
    
    if ([destination respondsToSelector:@selector(setColorAsNum:)]) 
        [destination setValue:[NSNumber numberWithInteger:MKPinAnnotationColorPurple] forKey:@"colorAsNum"];

        [destination addObserver:self forKeyPath:@"colorAsNum" options:NSKeyValueObservingOptionNew context:NULL];
    
    [self presentModalViewController:navController animated:YES];

在我的 observeValueForKeyPath 方法中:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
    DetailMapViewController *destination = (DetailMapViewController *)object;
    [destination removeObserver:self forKeyPath:@"mapTypeAsNum"];
    [destination removeObserver:self forKeyPath:@"colorAsNum"];

    if ([keyPath isEqualToString:@"mapTypeAsNum"]) 
        if ([object isKindOfClass:[DetailMapViewController class]]) 
            id mapType = [change objectForKey:NSKeyValueChangeNewKey];
            self.mapView.mapType = [mapType integerValue];
        
    
    else if ([keyPath isEqualToString:@"colorAsNum"]) 
        if ([object isKindOfClass:[DetailMapViewController class]]) 
            id pinColor = [change objectForKey:NSKeyValueChangeNewKey];
            MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[self.mapView viewWithTag:10];
            annotationView.pinColor = [pinColor integerValue];
        
    

问题是如果我不更改 DetailViewController 中的引脚颜色或地图类型来调用 observeValueForKeyPath 方法,我最终会根据控制台泄漏观察信息。所以我想知道在这样的场景中我在哪里添加观察者和删除观察者。在过去使用 NSNotificationCenter 时,我会在 dealloc 中删除观察者,并在呈现与上述代码类似的 detailViewController 之前添加观察者。但是对于 KVO,我不确定它是如何工作的。有什么想法吗?谢谢。

【问题讨论】:

【参考方案1】:

您应该在模态视图关闭之前停止观察。

完成此操作的最佳方法是让模态视图在准备好关闭时通知您的 MKMapView 控制器,并让 MKMapView 停止观察,然后关闭模态视图。

【讨论】:

那么在DetailController的viewDidDisappear中,发布通知告诉MKMapView停止观察? 当然,这是一种方式。另一个是委托它(我认为这更“典型”)。 @Inafziger 喜欢这篇文章吗? ***.com/questions/3730617/…

以上是关于显示 DetailViewController 时在哪里为 KVO 添加和删除观察者的主要内容,如果未能解决你的问题,请参考以下文章

显示 DetailViewController 时在哪里为 KVO 添加和删除观察者

在 UIWebView 中单击链接时,iOS 从 DetailViewController 开始

Obj-C:从导航控制器中的 detailViewController 传回参数

在 Master-Detail 应用程序的 DetailViewController 中显示文档

数组索引超出范围

弹出 MasterViewcontroller 时推送 DetailViewController