1

在我的应用程序中,我有一个工作线程,它围绕着做大量的处理。在处理过程中,它会将更新发送到使用信息更新 GUI 元素的主线程。这是用performSelectorOnMainThread. 为简化代码,对这些更新没有限制,它们以高速率(每秒数百或数千)发送,并且waitUntilDonefalse. 调用的方法只是获取变量并将其复制到视图控制器的私有成员。其中一些直接更新GUI(因为我很懒!)。每隔几秒钟,工作线程调用一次performSelectorOnMainThreadwaitUntilDone设置为true(这与保存当前计算批处理的输出有关)。

我的问题:这是安全使用performSelectorOnMainThread吗?我问是因为我最近遇到了一个问题,即我的显示值停止更新,尽管后台线程继续工作而没有问题(并产生正确的输出)。由于它们以这种方式被馈送值,我想知道它是否可能达到了消息数量的限制。我已经检查了常见的问题(溢出、泄漏等),一切都很干净。但是,我无法重现该问题。

4

1 回答 1

1

为简化代码,对这些更新没有限制,它们以高速率(每秒数百或数千)发送,waitUntilDone 为假。

是的。不要那样做。甚至不是为了在内部应用程序中的懒惰。

除了使主运行循环无响应之外,它还可能导致各种潜在问题。

最重要的是,它会使您的工作线程因 CPU 周期而饿死,因为您的主线程会不断旋转,试图在消息到达时尽快更新 UI。鉴于绘图通常在辅助线程中完成,这可能会导致更多的线程争用,从而进一步减慢速度。

其次,所有这些消息都会消耗资源。可能有很多,也可能是相对稀缺的,具体取决于实施细节。

虽然不应该有一个限制,但可能有一个实际限制,当超过这个限制时,事情就会停止工作。如果是这种情况,这将是系统中的一个错误,但除了控制台日志显示“消息太多,速度太快,减少。”之外,不太可能修复这个错误。

不过,它也可能是您的代码中的错误。线程之间的状态转移是一个充满陷阱的领域。您确定您的跨线程通信代码是防弹的吗?(而且,如果它是防弹的,它很可能会为您的数千/秒更新通知带来巨大的性能成本)。

限制更新并不难。虽然评论的建议都是合理的,但它可以更容易地完成(NSNotificationQueue 很棒,但可能会过度杀伤,除非您从计算中的许多不同位置更新主线程)。

  • 每当您通知主线程并将日期存储在 ivar 中时创建一个 NSDate
  • 下次去通知主线程,检查是否超过N秒
  • 如果有,请更新您的 ivar
  • [奖励性能] 如果所有日期比较都太昂贵,请考虑重新访问您的算法以将“立即更新”触发器移动到不那么频繁的地方。除此之外,创建一个 int ivar 计数器,并且只检查每 N 次迭代的日期
于 2013-03-25T15:41:16.890 回答