NetNewswire处理螺纹

2021-03-22 14:37:40

所有代码ui代码和否则 - 是主线程的默认位置。在主线程上运行的同步代码是最简单的代码,它最不可能触发奇怪,间歇性错误。

换句话说:我们尽可能地尝试,不要使用队列或线程。我无法强调这一点:处理并发性的最佳方式就是不是这样做。

虽然给定的对象(或小系统)可以在内部使用串行队列,但它永远不会让这事实超出自己的边界。

解析RSS源是纯功能。由于它确实需要一些时间(虽然比你想象的少),它可以在背景中完成串行队列。结果通过主线程上的回调返回(见上文)。

这些类型的东西对于背景处理很好,因为它们完全孤立 - 解析饲料不会影响状态。它没有任何通知。一旦完成,它就是回调,有一个对象。

对于此,还有其他示例(解码JSON或图像数据),我们处理相同的方式。

我们的模型对象是普通的OL'类和结构。用于读取和写入的API是仅限主线程的,并且它们在异步时呼叫,但总是在主线程上。

但是,在数据库代码中,是一个串行队列。然而,它完全是该代码的内部,并对其余的应用程序完全看不见。

当数据库代码发送任何通知时,它会在主线程上执行此操作。它不会影响任何应用程序状态。

如果您在线程上进行搜索.Istainthread,您会发现一堆......

......以及XCTasserttrue(Thread.Irmainthread)的一个示例。如果我们在主线程中,我们就不会测试。

(我不介意更多的前提(Thread.Irmainthread)而不是我们现在所做的更多。)

您对此模型可能会持怀疑态度,但我会提醒您NetNewswire响应,令人愉快地快速。它也 - 到目前为止 - 我在长期职业生涯中工作的最稳定和最糟糕的应用程序。而这一部分是我们的线程模型。

关于这个模型的一个很好的事情是开发人员知道,只是通过查看它们的位置,代码正在运行的线程。这几乎总是主要的。但是,如果你正在研究RSS解析器或类似的情况,你知道它真的无关紧要,如果你正在进行数据库或类似的话,那么你正在使用串行队列很明显。

随着我们采用的组合,SWIFTUI和未来的SWIFT语言更改支持并发,我们将继续使用此模型。我们的实现的详细信息可能会更改,但模型将保持不变:在几个情况下使用除此之外的主线程,并确保这些案例无法在外面泄露其队列的知识或行为。

一些我所知道的开发人员似乎认为同意良好使他们成为Badass。其他人似乎认为高级开发人员必须享有并发,所以应该也是如此。

但是,高级开发人员擅长通过开发简单,简单,一致的模型来消除并发性,以便为应用程序及其组件遵循。

这是因为,人类对人类来说太难了解和维护。也许你可以创建一个大量使用它的系统,并且有一天都有正确的。但想到你的团队!即使你是一个独奏开发人员,你和你和六个月也让你成为一个团队。

我知道你担心阻止主线程。但考虑一下:更容易修复主线程阻滞剂的方式,它是修复由于线程引起的奇怪,间歇性错误或崩溃。

使用主线程阻滞剂,使用仪器中的时间分析器并弄清楚正在发生的事情。可能是需要移动到背景串行队列的东西 - 或者更有可能有一个可以改进的数据结构或算法,或者您发现您的应用程序正在做出不必要的工作(或两者)。

我怀疑大多数应用程序没有明确的并发模型。如果你的是,那么很棒!跳过这篇文章的其余部分。 :)

如果您想移动到我上面描述的模型,我会从几件事开始。

确保应用程序帖子发布在主线程上的每一个通知。在通知处理程序中,添加Assert(Thread.Irmainthread)

如果您不使用通知,请将该建议应用于KVO或您可能使用的其他任何内容。

我选择通知和KVO的原因是因为它们是一场距离的幽灵动作 - 当你正在进行通知处理方面时,你不知道通知发布的线程,开发人员往往会假设这是主线程。这是线程泄漏的公共场所,导致错误和崩溃。 (意外多线程是我们平台的祸害。)

下一步可能会查看您使用队列的地方,并找出哪些可以移动到主线程。而且,当您无法移动到主要时,构建更好的墙壁:让API调用回主线程,并不会让这些队列的事实从API后面泄漏出来。不要让线程泄漏。

与此同时,您可能会发现您必须常常作为防御措施派遣主要队列。

理想情况下,当它是该线程模型的一部分时

但是,在您的应用程序到达之前可能有一段时间,那没关系。 (提示:请考虑有时调用DispatchQueue.main.async的情况.Async正在主题上运行的代码中发生。异步部分是真实的,您可能并不总是想要:有时您可能需要立即运行代码 当已经在主线程上。有时不是。) 最后:将所有断言(Thread.Irmainthread)更改为前提条件(Thread.Irmainthread) - 在违反线程模型时,使您的应用程序崩溃。 能够做到这一点 - 知道它不会旅行 - 是一个很好的地方。 🐣🐥🎉