2

我已经成为 KVO/KVC 的忠实粉丝。我喜欢它让我的 MVC 架构保持整洁的方式。但是,当我在我正在设计的 3D 渲染应用程序的内部渲染循环中使用 KVO 时,我不喜欢我所招致的巨大性能损失,其中消息将以每秒 60 次的速度为每个观察对象触发 - 可能是数百次。

加速 KVO 的技巧和窍门是什么?具体来说,我正在观察一个标量值 - 而不是一个对象 - 所以包装/展开可能会杀死我。我也在设置和拆除观察

[foo addObserver:bar forKeyPath:@"fooKey" options:0 context:NULL];
[foo removeObserver:bar forKeyPath:@"fooKey"];

在内循环内。也许我正在为此受到打击。

我真的,真的,想要保持 KVO 为我提供的巨大灵活性。有哪位速度狂人可以伸出援手吗?

干杯,道格

4

1 回答 1

4

Objective-C 的消息分发和其他功能针对它们提供的功能进行了调整并且速度非常快,但它们仍然没有接近调整 C 用于计算任务的潜力:

NSNumber *a = [NSNumber numberWithIntegerValue:(b.integerValue + c.integerValue)];

比:

NSInteger a = b + c;

由于这个原因,实际上没有人对Objective-C中的对象进行数学运算(好吧,而且语法很糟糕)。

Objective-C 的强大之处在于你有一个很好的表达性的基于消息的对象系统,你可以扔掉昂贵的部分并在需要时使用纯 C。KVO 是昂贵的位之一。我喜欢 KVO,我一直在使用它。它的计算成本很高,尤其是当您有很多观察到的对象时。

内部循环是您一遍又一遍地运行的一小段代码,任何事情都会一遍又一遍地完成。如果需要,您应该在此处消除 OOP 功能,您不应该分配内存,您应该考虑将方法调用替换为静态内联函数。即使您以某种方式设法在渲染循环中获得可接受的性能,它的性能也会比您从那里获得所有昂贵的通知和调度逻辑要低得多。

如果您真的想尝试继续使用 KVO,可以尝试以下几件事来加快速度:

  1. 在您的对象中从自动切换到手动 KVO。这可以让您减少虚假通知
  2. 聚合更新:如果您在某个时间间隔内的中间值不相关,并且您可以推迟一段时间(如下一个动画帧)不发布更改,请标记需要发布更改并等待相关计时器关闭,您可能会避免一堆短暂的中间更新。您还可以使用某种代理来聚合多个对象之间的相关更改。
  3. 合并可观察属性:如果您在一种类型的对象中有大量可能更改的属性,您最好让一个“hasChanges”属性观察并让观察者查询属性。
于 2009-07-21T08:17:29.450 回答