Tag: 队列

iOS中的队列多线程

要创建吸引用户每天使用它的iOS应用,精美的设计必不可少,因此应用中的快速体验也至关重要。 几个月前,我下载了一个教您如何烹饪的应用程序。 我在使用它的10分钟内删除了它。 为什么? 图片无法加载,我被卡在加载标牌上很长时间(例如1-2分钟?)。 这很令人沮丧,因为我想看看教程中的菜式。 好吧,这没有发生。 那么到底需要发生什么呢? 排队是有益的,也是麻烦的 iPhone内有一个CPU(中央处理单元)。 CPU一次只能执行一项任务。 待处理的任务排成一行 。 将排队视为排队等候餐厅座位的人。 当服务员有空位时,将排在第一位。 先进先出(FIFO)。 那么,我们的手机又如何如此迅速地响应我们的触摸和动作? 答案是:多线程。 多线程允许处理器创建并发线程以便在处理器之间进行切换。 结果,可以同时执行多个任务。 每个线程都有自己的队列。 就像剧院票房的台词一样。 一条线供客户购买机票,另一条线供客户打印预订的机票。 人们在每一行同时进出。 相同的概念适用于iOS生态系统。 如果我们在应用程序内部具有多线程,则不会发生像烹饪应用程序这样的悲剧。 我们不必从服务器获取配方,而不必等待它完成然后显示图像。 让我们看看我们如何做到这一点! 在iOS中引入Grand Central Dispatch(GCD) Grand Central Dispatch将任务分配给不同的线程(不同的队列)。 例如,主线程负责从服务器获取配方数据,而后台线程将更新UI并显示图像。 因此,该应用程序保持响应状态。 很好,对吗? GCD API围绕 DispatchQueue 。 此类使我们能够创建/修改队列,以及同步或异步分配代码 和更多。 同步方式 为了。 当您执行同步操作时,以后出现的所有内容都必须等待上一个操作完成才能开始。 另一方面,当您异步执行某项操作时,以下代码可以立即运行。 在其他队列上启动任务后,它将立即将控件返回到当前队列,而无需等待其结束。 异步方法不会阻止当前队列上的任务执行。 如您所见,当队列给我们带来麻烦时,我们可以通过它的变体来巧妙地处理它。 请继续关注第二部分–代码中的GCD实现!

iOS 2018系列:破解iOS采访或成为iOS专家(6)

第6章:DispatchGroup和OperationQueue 最近,我不得不做一堆异步任务,我只想在所有任务完成时得到通知。 该博客将介绍两种简单的方法:DispatchGroup和OperationQueue。 在这篇文章中,我们将同时介绍它们。 派遣组 如果您正在开发一个不使用Operations的项目,并且不想重构任何现有代码,则DispatchGroup是一个功能强大的API,可以将这些任务组合为一个任务。 情况1 :计算三个不同线程上三个数组的总和,一旦所有线程完成其执行,我想使用该结果。 在考虑解决方案之前,让我们学习一些与调度组相关的API。 enter () —明确指示一个块已进入该组。 leave () -明确表示该组中的一个块已经完成。 func notify (qos:DispatchQoS =默认值,标志:DispatchWorkItemFlags =默认值,队列:DispatchQueue,执行工作:@escaping @convention(block)()-> Swift.Void)– 当一组先前提交的块对象完成时,将要计划的块调度到具有指定服务质量类和配置的队列中。 解决方案 :这三个API将帮助我处理上述情况,让我们学习如何使用它们。 我在下面写了添加数组元素并返回的函数 此函数使用DispatchQueue.global()。async创建线程,并使用DispatchQueue.concurrentPerform创建循环以添加infoArr的所有元素(类似于for循环),然后返回名为block()的完成处理程序。 下面的函数将创建三个并行计算总和的线程,一旦线程完成,它将调用dispatchgroup的notify函数。 调用notify函数后,我们将拥有所有三个数组的和,并且我们可以将其传递给completeizationBlock()。 操作和操作队列 它是一个抽象类,您需要对其进行子类化才能使用。 如果您只想执行一小段代码或调用一个方法,则可以使用BlockOperation和NSInvocationOperation代替子类化Operation。 情况2:使用操作计算三个不同线程上三个数组的总和,一旦所有线程完成其执行,我都想使用该结果。 解决方案:创建OperationQueue实例以添加操作,创建三个BlockOperation以添加数组的总和,然后在操作之间添加依赖项(因为我们需要获得实际上不依赖的最终总和),一旦我们以任何顺序将这三个块操作添加到操作队列中,这无关紧要,在第三块上注册完成块以获取最终总和。 输出:下图显示-调用块的顺序和最终求和结果 有障碍的并发队列 并发队列中的任务可以任何顺序执行,并且可以同时启动。 与上述串行队列相比,这是非常快的。 但是,由于我们可能在写书的同时阅读,所以我们会遇到读者-作家问题。 如果有一种方法可以确保在读取时不进行写入操作,而在使用并发写入时不进行读取操作,该怎么办? 好吧,有一种方法可以使用带有Barrier的Concurrent Queue 。 如果我们采用上面的并发代码,并为写操作插入一个障碍,那么我们将确保在执行队列中的所有读取之后进行写操作,并且确保在写入时不会发生任何读操作。 使用带有障碍的并发队列可以帮助我们改善和加快代码的速度,同时消除读写器问题,这对于单例来说也很重要。 奖励时间:#import和@class之间的区别 “ #import”将整个有问题的头文件带入当前文件; 还包括该文件#imports的所有文件。 另一方面 , @class (当单独使用带有某些类名的行时)告诉编译器“嘿,您很快就会看到一个新令牌; 这是一堂课,所以要这样对待)。 当您有可能使用“ […]

GCD –不再冻结您的应用程序😎

您是否曾经见过您的应用程序冻结或感觉不舒服? 这样的事情。 我必须告诉你,这不是一个断点,应用程序已完全冻结,我无法按下另一个按钮,我将向您解释原因。 该按钮仅运行以下代码 同样重要的是要注意每个队列都有不同的优先级,如下所示 交互式用户的优先级高于用户实例化的优先级,因此,您需要注意派遣队列需要哪种类型的服务质量。 如您所见,蓝点占主导地位,这是因为🔵蓝点的打印优先级高于🔴红点的队列,计数也很明显,蓝点打印了115点,而红点只打印了115点。 41。 为了避免冻结,我们可以将所有工作负荷放在一个队列中,还可以添加取消流程的功能,因为用户可能希望取消流程并返回到您的应用程序。 代码在哪里? 如果您想自己运行,可以下载此示例的我的仓库! 编码愉快! 🚧 chuynadamas / GCD-BasicExample GCD-BasicExample –使用工作项和调度队列的基本示例 github.com

可爱的队列

我知道你们已经在这个队列上等待了太长时间。 因此,让我们深入研究问题代码。 与堆栈不同,队列全部与FIFO有关,请考虑FIFA,除非并非如此。 当您处于排队状态时,您希望排队的第一个人将首先得到服务。 考虑到这一点,让我们来构建它! 我们创建了一个变量,它将所有项目组合在一起。 然后,我们创建了一个将追加新项目的函数。 附加的项目将进入队列的末尾。 此外,当我们使一个项目出队时,我们需要检查是否还有一个项目开始。 不要成为冒昧的程序员,不要承担任何责任,检查自己并检查可选组件! 因此,一旦我们保护了队列中的项目,我们还将检查第一个元素是否确实存在,如果确实存在,那就让我们返回它! 但是,如果没有,则应该返回nil,因为队列中没有任何内容! 最后,偷看方法应该很明显,您希望看到谁在队列中,并且您最关心的项目或人员还是第一人。 让我们看一个实际的例子: 因此,这里有Lannisters。 当我们第一次窥视内部时,我们的队列中没有兰尼斯特。 但是,将其中的三个相加后,您会看到我们将返回我们也预计将在本赛季死亡的Lannister。 队列和塞雷的死对任何人都不应该感到惊讶。 当尝试为Queue编写代码时,请尝试与用户保持同理心,而我的意思是想想您正在排队或为某人服务的时间……您将如何帮助他们? 这种心态应该可以帮助您编写队列代码并记住其核心概念!