GCD阻止不更新NSCollectionView

时间:2010-07-30 23:40:10

标签: cocoa cocoa-bindings grand-central-dispatch

我有一个Cocoa应用程序,可以监听通知并将更新发布到由NSMutableArray监控的NSCollectionView。通知以大量形式到达,因此我想使用不同的队列来处理它们并相应地更新阵列。

现在我正在使用addObserverForName:object:queue:usingBlock注册通知,当我为队列指定NSCollectionView时,它工作正常(数组和[NSOperationQueue mainQueue]都已更新)。但是,当我创建自己的队列(使用[[NSOperationQueue alloc] init])时,NSCollectionView停止更新。使用调试器我可以看到它正在监视的数组正在更新。

这是一个错误,还是我错过了什么?

1 个答案:

答案 0 :(得分:3)

使用AppKit绑定时,任何发布的KVO通知都需要在主线程上发生才能使事情正常工作。因此,如果直接从后台线程中的通知处理程序修改数组,NSCollectionView将在该线程上接收任何触发的KVO通知,而不是主线程。发生这种情况时的行为是未定义的,最多不会起作用,而最坏的情况可能会导致崩溃或其他奇怪的行为。

如果通知的数量足够大,以至于每次通知的更新都是性能问题,我建议使用以下两种方法之一:

  • 查看NSNotificationQueue(与NSOperationQueue无关),它支持将多个发布的NSNotifications合并到发送给您的观察者的单个通知中。
  • 在后台收听通知,就像你正在做的那样,但是你自己批量修改,也许只发布每次第N次更改或者如果没有更多的时间到达更新,则发布计时器以发布更新。然后,当您对阵列执行实际更新时,尝试将其缩小到尽可能少的工作,然后将该工作放在主线程上。在mainQueue上调用-[NSOperationQueue addOperationWithBlock:]是一种简单的方法。