GCD 阻止不更新 NSCollectionView

发布于 2024-09-12 02:08:24 字数 438 浏览 6 评论 0原文

我有一个 Cocoa 应用程序,它侦听通知并将更新发布到由 NSCollectionView 监视的 NSMutableArray。通知大量到达,因此我正在考虑使用不同的队列来处理它们并相应地更新数组。

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

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

I have a Cocoa app that listens for notification and posts updates to an NSMutableArray monitored by a NSCollectionView. The notifications arrive in large volumes so I was thinking to use a different queue to process them and update the array accordingly.

Right now I am using addObserverForName:object:queue:usingBlock to register for notifications, and it works fine (both the array and NSCollectionView are updated) when I specified [NSOperationQueue mainQueue] for the queue. However when I created my own queue (using [[NSOperationQueue alloc] init]), then the NSCollectionView stops updating. Using the debugger I can see the array it's monitoring is being updated though.

Is this a bug, or did I miss something here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

友谊不毕业 2024-09-19 02:08:24

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

如果通知数量确实足够多,以至于每个通知的更新都会造成性能问题,我建议您选择以下两件事之一:

  • 看看 NSNotificationQueue (与 NSOperationQueue 无关),它支持将多个已发布的 NSNotification 合并为发送到的单个通知你的观察者。
  • 像您正在做的那样,在后台监听通知,但自己批量进行更改,也许只发布每第 N 个更改,或者在 X 时间内没有更多更改到达时触发计时器来发布更新。然后,当您对数组执行实际更新时,尝试将其范围缩小到尽可能少的工作,然后将该工作放在主线程上。在 mainQueue 上调用 -[NSOperationQueue addOperationWithBlock:] 是一种简单的方法。

When working with AppKit bindings, any KVO notifications that get posted need to happen on the main thread in order for things to work correctly. So, if you modify the array directly from your notification handler in a background thread, the NSCollectionView will receive any triggered KVO notifications on that thread and not the main thread. The behavior when this happens is undefined, and at best won't work, while at worst could cause crashes or other strange behavior.

If the notifications do come in large enough quantities that updating on every notification is a performance problem, I'd recommend one of two things:

  • Take a look at NSNotificationQueue (no relation to NSOperationQueue), which supports coalescing multiple posted NSNotifications into a single notification sent to your observer.
  • Listen for the notifications in the background like you're doing, but batch up the changes yourself, perhaps posting only every Nth change or having a timer fire to post an update if no more have arrived in X amount of time. Then when you perform the actual update on the array, try to narrow that down to as little work as possible, then put that work on the main thread. Calling -[NSOperationQueue addOperationWithBlock:] on the mainQueue is an easy way to do that.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文