GCD 块不更新 NSCollectionView
Posted
技术标签:
【中文标题】GCD 块不更新 NSCollectionView【英文标题】:GCD blocks not updating NSCollectionView 【发布时间】:2010-07-30 23:40:10 【问题描述】:我有一个 Cocoa 应用程序,它监听通知并将更新发布到由 NSCollectionView
监控的 NSMutableArray
。通知大量到达,因此我正在考虑使用不同的队列来处理它们并相应地更新数组。
现在我正在使用addObserverForName:object:queue:usingBlock
注册通知,当我为队列指定[NSOperationQueue mainQueue]
时,它工作正常(数组和NSCollectionView
都已更新)。但是,当我创建自己的队列(使用[[NSOperationQueue alloc] init]
)时,NSCollectionView
将停止更新。使用调试器,我可以看到它正在监视的数组正在更新。
这是一个错误,还是我在这里遗漏了什么?
【问题讨论】:
【参考方案1】:在使用 AppKit 绑定时,发布的任何 KVO 通知都需要在主线程上发生,才能正常工作。因此,如果您直接从后台线程中的通知处理程序修改数组,则 NSCollectionView 将在该线程而不是主线程上接收任何触发的 KVO 通知。发生这种情况时的行为是未定义的,充其量不会起作用,而最坏的情况可能会导致崩溃或其他奇怪的行为。
如果通知的数量确实足够多,以至于更新每个通知都会导致性能问题,我会推荐以下两种方法之一:
查看NSNotificationQueue(与 NSOperationQueue 无关),它支持将多个已发布的 NSNotification 合并为一个发送给观察者的通知。 像您正在做的那样在后台收听通知,但您自己批量更改,可能只发布每第 N 个更改,或者如果在 X 时间内没有更多更新,则使用计时器触发发布更新。然后,当您对数组执行实际更新时,尝试将其缩小到尽可能少的工作,然后将其放在主线程上。在 mainQueue 上调用-[NSOperationQueue addOperationWithBlock:]
是一种简单的方法。
【讨论】:
以上是关于GCD 块不更新 NSCollectionView的主要内容,如果未能解决你的问题,请参考以下文章
如何在目标 c 中使用 GCD dispatch_async 调用/编写以下方法