问题标签 [ios-multithreading]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
3029 浏览

ios - 为什么我们需要调用主线程进行 UI 更新?

我知道我们在更新 UI 时必须调用主线程。但我无法解释我的队友为什么我们必须这样做,以及为什么 Swift 不自动这样做。

他们曾经像这样调用 self.present() :

但我知道你应该这样称呼它:

我实际上想确保始终在主线程上调用该方法,但我不知道如何...另一个问题是:为什么我必须确保在主线程而不是 Swift 上调用此方法?当有人调用此方法时,总会有 UI 更新。

0 投票
1 回答
438 浏览

ios - 如何利用 iOS 中的多个处理器内核来实现访问共享数据的循环的最快/最短计算?

当在 iOS 上运行的 Swift 中的数组上运行 for 循环时,我想利用整个 CPU,因为我觉得这在理论上应该可以加快计算速度。然而我的结果是相反的,在一个DispatchQueue而不是多个DispatchQueues 上运行所有东西,实际上执行得更快。我将提供一个示例,并想知道为什么单线程方法更快,如果可能的话,我仍然可以通过正确利用多个 cpu 内核来降低计算所需的时间?

对于那些只想查看我的意图代码的人可以跳过,因为下一节仅详细说明我的意图方法

我在示例中提供的意图:

我正在确定地图上的一条线(汽车行驶的轨迹,每秒的纬度和经度)是否在某个预定义的区域内,地图上的多边形(整个区域的纬度和经度)。为此,我有一个函数可以计算单个点是否在多边形内。我正在使用 for 循环来遍历汽车行驶轨迹中的每个位置,并使用该函数检查该点是否在多边形内。如果每个跟踪的位置都在多边形内,则整个跟踪的汽车行程都发生在所述区域内。

我将 iPhone X 用于开发目的,并利用整个 CPU 来加速计算。

我的做法:

在提供的示例中,我有 3 个变体,导致计算所需的以下时间(以秒为单位):

第一种方法是最简单的,即不使用多个DispatchQueue.

第二种方法利用DispatchQueue.concurrentPerform(iterations: Int). 我觉得这可能是满足我需求的最佳解决方案,因为它已经实施并且似乎是为我的确切目的而设计的。

DispatchQueue第三种方法是我自己的,它根据操作系统报告的活动 CPU 内核的数量将阵列的大致相等的部分安排到在 s 上运行的 for 循环。

我也尝试过使用inout参数(通过引用调用)的变体,但无济于事。时间保持不变,因此我没有提供更多代码来混淆问题。

我也知道,一旦我发现一个不在多边形内的点,我就可以返回该函数,但这不是这个问题的一部分。

我的代码:

示例数据

我已经为那些希望有数据运行测试的人上传了两个 json 文件。这是导致我记录时间的相同输入。

追踪到的乘车:链接到 json 文件 区域/区域:链接到 json 文件

0 投票
1 回答
35 浏览

performance - 在 setter - getter 中同步类属性是否会影响线程安全性?

我在类属性中有竞争条件。一个线程正在读取它,另一个线程正在写入。现在我想出了一个解决方案来同步该属性的 getter 和 setter。问题是这会影响应用程序的性能吗?如果是,除了同步属性还有其他解决方案吗?

0 投票
1 回答
682 浏览

swift - Xcode 错误地报告 Swift 访问竞争条件

我相信 XCode 错误地报告了我的 Swift Access Race SynchronizedDictionary- 或者是吗?

我的SynchronizedDictionary样子是这样的:

以下测试代码将触发“Swift Access Race”问题(当为方案打开 Thread Sanitizer 时):

Swift Race Access 如下所示:

快速比赛访问 我真的没想到这里会有访问竞争条件,因为SynchronizedDictionary应该处理并发。

我可以通过在测试中将获取和设置包装在类似于实际实现的 DispatchQueue 中来解决此问题SynchronizedDictionary

...但这已经发生在内部SynchronizedDictionary- 那么为什么 Xcode 报告访问竞争条件?- Xcode 有错,还是我遗漏了什么?

0 投票
0 回答
184 浏览

ios - iOS OperationQueue:并发异步操作块屏

我对 iOS 中的多线程非常陌生,并且在执行我的任务时遇到了一些困难。我真的很感谢更有经验的程序员的任何帮助。

我有一个 URL 地址,作为起点,我向其发出请求,检查一些信息,并检索该网页上包含的所有 URL 地址。在此之后,我需要一次又一次地对新的 URL 地址执行相同的操作,直到检查特定数量的 URL。

我决定使用OperationsOperationQueues,因为我还需要能够选择最大并发操作数。

我创建了一个自定义异步操作LoadOperation并将其应用于存储在数组中的每个 URL。在完成块中,我将新的 URL 添加到数组中,并以递归方式调用相同的函数。

我还创建了两个队列:

  • 一个并发请求,

  • 用于访问共享属性的序列号,如下所示:

这是我的搜索功能:

我不知道为什么:

  1. 当我运行应用程序时,屏幕冻结。即使我所有的队列都在后台(qos:实用程序)。

  2. 有时当我尝试滚动 UITableView 时,sigabort由于index out of range,即使我尝试访问串行队列中的所有属性。

这是一个数据源代码:

和功能来自presenter

0 投票
1 回答
1948 浏览

ios - 从后台线程播放 AVAudioPlayer 实例有时会失败

我正在尝试使用 Swift 5 中的 AVAudioPlayer 实例从后台线程播放声音。大多数情况下,它会成功。但是有时音频播放器无法播放声音。

似乎调用 play() 两次,或者连续调用 prepareToPlay() 然后 play() 以某种方式解决了问题,但这对我来说似乎不是一个好的解决方案,因为我担心这仍然不是保证播放成功。

我按以下顺序调用方法:

我无法弄清楚问题所在——我真的只想调用一次 play() 并让一切正常。

0 投票
3 回答
2537 浏览

ios - 完成处理程序调用两次(带线程)

我目前正在 Xcode 10 Playground (Swift 5) 中测试这段代码:

问题是“hi”和“nil”都被打印出来了。

如果我摆脱线程,它可以正常工作,但它似乎DispatchQueue.main.async在第一个有机会返回之前到达第二个。

在我的实际代码中的“一些缓慢的东西”中还有很多东西在发生,if但我不能依赖在调用第二次返回之前花费足够长的时间来返回。

我该如何做到这一点:让函数在后台线程中运行,但在主线程上只返回一次(就像通常没有线程的代码一样)?

0 投票
1 回答
2223 浏览

objective-c - 多线程渲染仅在 iOS 13 上崩溃

在我的游戏引擎中,我可以选择启用多线程渲染。在 iOS 12(及更低版本)中,我的应用程序没有崩溃。

我没有更改我的代码中的任何内容,但它在 iOS 13 上崩溃了。

当我禁用多线程渲染选项时,它没有崩溃。iOS 13 中的线程系统一定有变化,但从他们的文档中找不到任何东西。

0 投票
1 回答
103 浏览

ios - .enforceQoS 标志如何提高优先级?

我试图增加并发队列中执行的块的优先级。我建议标志enforceQoS适合此目的。正如苹果文档所说:

该标志将块的服务质量等级优先于与当前执行上下文关联的等级,只要这样做不会降低服务质量。

假设有一个队列:

我们还有几个DispatchWorkItem任务,其中一些是:

我的问题很简单:Apple 是否保证 item2 提前执行?

我在操场上玩了一会儿,可惜没有透露出这面旗帜的任何优势,结果绝对混乱。官方文档在这件事上也没有帮助。

非常感谢。

0 投票
2 回答
817 浏览

ios - 同步/异步的行为是否类似于串行/并发,即它们是否都控制 DispatchQueues 或仅同步/异步控制线程

stackoverflow 上的大多数答案都暗示同步与异步行为与串行与并发队列概念差异非常相似。就像@Roope 的第一条评论中的链接一样

我已经开始认为 Serial 和 concurrent 与DispatchQueue和 sync/async 有关如何在线程上执行操作。我对吗?

就像如果我们有DQ.main.sync那么任务/操作闭包将在这个串行(主)队列上以同步方式执行。而且,如果我这样做了,DQ.main.async那么任务将在其他一些后台队列上异步获取,并且在完成时将返回对主线程的控制。而且,由于 main 是一个串行队列,它不会让任何其他任务/操作进入执行状态/开始执行,直到当前的闭包任务完成执行。

然后, DQ.global().sync将在已分配其任务/操作的线程上同步执行任务,即,它将通过阻止该特定线程上的任何上下文切换来阻止该线程执行任何其他任务/操作。而且,由于 global 是一个并发队列,它将继续将其中存在的任务置于执行状态,而不管先前的任务/操作的执行状态如何。

DQ.global().async将允许在已放置操作闭包以执行的线程上进行上下文切换

这是对上述 dispatchQueues 和同步与异步的正确解释吗?