为什么要并发?
一旦您向应用程序添加了繁重的任务(例如数据加载),它就会减慢您的UI工作甚至冻结它。并发使您可以“同时”执行2个或更多任务。这种方法的缺点是线程安全性并不总是那么容易控制。例如,当不同的任务想要访问相同的资源时,例如尝试在不同的线程上更改相同的变量或访问已经被不同的线程阻塞的资源。
我们需要注意一些抽象。
- 队列。
- 同步/异步任务性能。
- 优先事项。
- 常见的麻烦。
Queue列
必须是串行或并发的。以及全球或私有。
使用串行队列,任务将一个接一个地完成,而使用并发队列,任务将同时执行,并且将按意外的时间表完成。与并发队列相比,同一组任务将在串行队列上花费更多的时间。
您可以创建自己的专用队列(串行或并发队列)或使用已经可用的全局(系统)队列。该主队列是唯一的串行队列所有的出全球队列。
强烈建议不要在主队列上执行不与UI工作相关的繁重任务(从网络中加载数据),而是在其他队列上执行这些任务,以保持UI冻结并响应用户操作。如果我们允许在其他队列上更改UI,则可以按不同的意外时间表和速度进行更改。某些UI元素可以在需要之前或之后绘制。它可能会使UI崩溃。我们还需要记住,由于全局队列是系统队列,因此系统可以在它们上运行其他一些任务。
服务质量/优先级
队列也有不同的QoS(服务质量),其中规定了任务执行优先级(这里从最高到最低):
.userInteractive - 主队列
.userInitiated -用户启动的任务哪个用户等待响应的一些
.utility -为任务这需要一些时间并且不需要立即响应,例如使用
data.background-用于与可视部分无关的任务以及对完成时间不严格的任务。
还有一个
.default队列,它不传输qos信息。如果这是不可能检测到的QoS的qos将在.userInitiated和.utility之间使用。
任务可以同步或异步执行。
常见问题。
程序员在开发并发应用程序时犯的最普遍的错误如下:
- 竞争状态 -在应用程序工作取决于代码部分执行的顺序时引起。
- 优先级倒置 -当较高优先级的任务由于某些资源被阻塞而等待较小优先级的任务完成时
- 死锁 -当一些队列无限等待源(变量,数据等)已被其中一些队列阻塞时。
永远不要在主队列上调用同步功能。
如果您在主队列上调用同步功能,它将阻塞队列,并且队列将等待任务完成,但是由于队列已停止,任务甚至无法启动,因此任务将永远不会完成。已经被封锁。这称为死锁。
什么时候使用同步?
当我们需要等到任务完成时。当我们确保某些函数/方法没有被双重调用时,Fe。如果我们有同步,并试图防止它被重复调用,直到完全完成。以下是针对此问题的一些代码:
如何找出导致iOS设备上的错误崩溃报告的原因?
DispatchQueue.main.sync
从后台线程调用会是错误的吗?