如何从Objective C KVO中的observationInfo方法获取信息?

时间:2013-07-11 16:40:19

标签: objective-c cocoa binding key-value-observing

observationInfo方法返回对象绑定的信息。我环顾四周但我不知道如何从字典中获取信息。任何人都能引导我走向正确的方向吗?

修改 如果任何人误解我说的话。我的课程已经全部符合KVO标准。现在,在将观察者添加到something对象后,self.something现在将具有绑定信息。如果我做[self.something observationInfo],这将返回一个字典。我想访问该词典的内容。

Apple docs说

  

为了提高性能,这个方法和setObservationInfo:可以   重写以将不透明数据指针存储在实例变量中。   此方法的覆盖不得尝试发送Objective-C消息   存储的数据,包括保留和释放。

所以我知道它可以做到......我的问题是怎样的?我看不到任何信息在线。

4 个答案:

答案 0 :(得分:7)

我怀疑你误解了-observationInfo / -setObservationInfo:的目的。由这些方法设置和获取的值对您来说是不透明的。换句话说,它的内容对系统框架是私有的,并且您不打算能够访问/解析它。您摘录的文档的评论是:

  

为了提高性能,这个方法和setObservationInfo:可以   重写以将不透明数据指针存储在实例变量中。   此方法的覆盖不得尝试发送Objective-C消息   存储的数据,包括保留和释放。

让我试着澄清这说些什么:

对于每次观察,框架都需要跟踪一些有关观察的私人数据,以便以后交付。如何存储该信息没有记录,但从概念上讲,它可能存储在一个映射中,其中键是对象的指针值,值是这种不透明的数据结构。

在特定的,对性能敏感的情况下,查找共享地图中的观察信息可能会显着影响性能(我自己从来没有看到过这种情况,但这并不是说它不能'发生)。在这些情况下,最好将指针直接存储为对象中的实例变量,这会将获取操作从映射查找更改为简单添加。从系统框架的角度来看,我敢打赌,地图查找成本通常通常远远不如繁琐(在大图中)繁琐,这可能是为了此目的在NSObject中放置一个实例变量(无论是否使用KVO,每个对象的大小都会增加8个字节 - 看起来很简单。)

存在

-observationInfo / -setObservationInfo:以允许您进行优化。如果您实现了此优化,这些方法也可以用来了解您的对象是否被观察(即信息值为nil?),这可能允许您对对象的行为进行其他更改。 / p>

如果您需要保留观察对象列表以及他们为其他目的观察的内容的详细信息,那么您需要通过覆盖addObserver:...removeObserver:...来自行完成,并添加代码以维护您自己的数据私有结构(同时仍然调用super。)

答案 1 :(得分:0)

这对我有用。

id anObserver = self;
NSString *observerString = [anObserver description];
NSString *str = [NSString stringWithFormat: @"%@", [aController observationInfo]];
NSRange rangeOfObserver = [str rangeOfString:observerString];
if (rangeOfObserver.location == NSNotFound) {
} else {
    [aController removeObserver:anObserver forKeyPath:@"selectionIndexes" context:NULL];
}

答案 2 :(得分:0)

id aInstance = (__bridge id)self.observationInfo;
NSArray *list = [aInstance valueForKey:@"_observances"];
for (id object in list) {
    id observer = [object valueForKey:@"_observer"];
    //id property = [object valueForKey:@"_property"];
    //NSString *keyPath = [property valueForKey:@"_keyPath"];
    NSString *keyPath = [object valueForKeyPath:@"_property._keyPath"];
    [self.stone removeObserver:observer forKeyPath:keyPath];

    NSLog(@"%@ %@", observer, keyPath);
}

答案 3 :(得分:-1)

您正在观察的对象必须符合KVO标准。这意味着您可以通过普通字典语法访问相关信息。例如:

[self.something addObserver:self
                  forKeyPath:@"cheese"
                     options:NSKeyValueObservingOptionNew
                     context:NULL];

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

  if ([keyPath isEqualToString:@"cheese"])
  {
    // Get the new key value
    [object valueForKey:keyPath];

    // See the changes for the key value
    NSLog(@"Changes: %@", change);
  }
  else
  {
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  }
}

The KVO docs at Apple.