问题标签 [dispatch-queue]

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 回答
50 浏览

ios - UICollisionBehavior and UIGravityBehavior not working as expected with DispatchQueue

I'm currently designing a UI for a framework I've been given that plays connect 4. This framework is encapsulated in a class called GameSession. I will not describe the ins and outs of it's API and how it operates. I don't believe it's important.

I believe I may be misunderstanding dispatch queues and I am using them incorrectly. But, I have searched endlessly and have not found anything that hints to a solution to my problem.

Here is a a short explanation on what is happening. The method that controls the moves is playGame(botStarts: Bool, atColumn: Int). In this method, a collision boundary is added at the correct row and column using a method called addBoundary(atRow: Int, atColumn: Int). Then, a disc is created using a method called dropDisc(atColumn: Int, color: UIColor). This method creates a custom UIView, adds it to the view on screen and adds collision and gravity behaviours. It falls until it reaches the previously added boundary.

In playGame() I am dropping the discs onto the screen using DispatchMain.Queue.async{dropDisc()}. But, every time I call playGame() for the second time and beyond, the custom discs are drawn at the top of the screen but they fail to fall. On the first iteration, they are drawn and fall as expected.

Below are the functions that I've referenced above.

Here is a screenshot of my screen: https://imgur.com/7M3fklo.

On the bottom row you can see the users disc (yellow) and the bots disc (red). These were added on the first call to playGame(). But, on the top, you can see the two discs that were added on the second call to playGame(). These do not fall.

No matter what I've tried

Any feedback is much appreciated!

0 投票
1 回答
7019 浏览

ios - 'dispatch_get_main_queue()' 的模糊使用

如何使用DispatchQueue该类替换以下适用于 iOS 的 Swift 代码?这是旧的 Swift 3 代码,最新的 Xcode 不会转换为 Swift 5。

它给了我一个错误,上面写着

'dispatch_get_main_queue()' 的模糊使用

dispatch_get_main_queue().

以下答案似乎是正确的答案,我想使用它,但有人可以告诉我这是正确的吗?斯威夫特版本

它说使用以下代码:

除了 using 之外DispatchQueue,我还有什么其他方法可以解决此错误?

0 投票
1 回答
413 浏览

ios - DispatchQueue 中的 CADisplayLink

我正在尝试在除主线程之外的线程中运行显示链接,但它根本不起作用。我创建了一个简单的调度队列queue = DispatchQueue(label: "xyz"),然后像往常一样创建显示链接:

选择器永远不会被调用。检查currentModeRunLoop我发现它是零。我错过了什么?

谢谢

0 投票
1 回答
389 浏览

swift - Swift - stopAnimating() - 只能在主线程中使用

我有一系列必须按顺序执行的任务,因此它们由 DispatchQueue 控制。为了通知用户他们正在离开,我启动了活动图标。但是,如果关闭主线程,我该如何停止?

从逻辑上讲,我想要实现的是:

这显然会产生运行时错误:“UIActivityIndicatorView.stopAnimating()必须仅从主线程使用”。

stopAnimating()它放在主队列中会如此快速地打开和关闭它,没有人会看到它。

什么是批准的方式调用这样的功能退出main队列?

非常感谢。Ps 我已经阅读了关于 SO 的类似问题的答案,但不太明白。

0 投票
2 回答
158 浏览

swift - 我应该如何将 DispatchGroup 用于两个 url 请求?

我将 DispatchGroup 用于两个 url 请求,但没有得到任何数据。我在没有 DispatchGroup 的情况下分别尝试了每种方法,效果很好。所以问题是我没有正确使用 DispatchGroup。请帮忙。

0 投票
1 回答
1948 浏览

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

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

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

我按以下顺序调用方法:

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

0 投票
1 回答
180 浏览

swift - Swift - 调度队列和 U/I 串行运行

我有一个应用程序的辅助 LaunchScreenViewController,它有一些动画,同时它收集三种类型的背景数据。

一切正常,但 DispatchQueues.async 的运行顺序是随机的。但是,如果我将它们更改为 DispatchQueues.sync 一切都以正确的顺序发生但运行得如此之快(即使有睡眠)你看不到动画。

这需要 .sync 但如何控制 U/I 以便我可以看到动画?(此处显示为,例如 self.subLogo1View.isHidden = true)

这是代码:

0 投票
0 回答
1060 浏览

ios - 用于应用后台处理的 iOS CoreBluetooth 调度队列

首先的问题是使用核心蓝牙作为中心角色将数据发送到蓝牙 LE 设备的最佳方式是什么。需要处理数据,如果在 UI 线程上运行,这需要足够的时间来导致 UI 线程出现问题。用户将在手机应用程序打开的情况下启动该过程,然后继续使用应用程序或关闭应用程序并期望数据继续发送到设备。

我发现了 2 种非常糟糕的方法,它们似乎有效

  • 将蓝牙 CBCentralManager 对象放在主队列上,有阻塞 UI 的风险
  • 忽略来自 iOS 蓝牙堆栈的指示,即它尚未准备好传输并有丢失数据的风险。

这似乎源于 iOS 线程/调度队列以及 iOS 蓝牙内部。

蓝牙 LE iOS 应用程序连接到蓝牙 LE 设备作为中心角色。CBCentralManager 根据苹果文档进行初始化。队列定义为:

用于调度中心角色事件的调度队列。如果值为 nil,则中央管理器使用主队列分派中央角色事件。

正如vladiulianbogdan 对 Swift 的回答所建议的那样:为蓝牙中央管理器选择队列,我们​​应该为 CBCentralManager 创建一个串行队列。这似乎是有道理的,有一段时间我一直在遵循这个建议。还有对 Swift CoreBluetooth 的 allprog 评论:如果 CentralManager 在单独的线程中运行 表明主队列将被挂起,但其他队列不会,这与我所看到的相反。

在为蓝牙使用串行队列时,最好使用与主线程不同的队列。有一个问题:回调:

别再被叫了。还有另一种方法可以检查外设是否准备好发送更多数据,CBPeripheral 有一个成员变量 canSendWriteWithoutResponse,如果可以发送,则返回 true。这个变量也开始重新调整 false 并且永远不会回到 true。

我从Sandeep Bhandari那里找到了这条评论,它说当应用程序进入后台时,所有队列线程都会停止,除非它们是苹果提供的后台模式之一。Biniou 发现他能够通过在视图控制器而不是应用程序委托中进行初始化来解决他的核心蓝牙背景问题。这对我来说没有意义。

我的应用确实在其 info.plist 中选择了核心蓝牙背景模式,因此它应该作为这些背景模式之一。我发现当我的应用程序进入后台时,该应用程序确实会继续处理数据。我看到来自每 100 毫秒运行一次的轮询循环的日志消息。

如果我从这些轮询循环中触发蓝牙 LE 写入,我可以继续发送数据。问题是我无法确定发送数据的安全速率,并且它非常慢或数据有时会丢失。

我不确定如何最好地处理这个问题。任何建议,将不胜感激。似乎无论我在后台做什么,我都失去了确定发送数据是否安全的能力。

我看到这条评论表明唯一的解决方案是改变蓝牙设备连接到手机的方式,是这样吗?我不确定此时更改硬件是否适合我。

理想的解决方案是找到一种方法将 CBCentralManager 放在它自己的串行队列上,但以这样一种方式创建该队列,即当应用程序进入后台时队列不会停止。如果有人知道该怎么做,我相信它会解决我的问题。

我当前代码的方式是这样的。当在 applicationDidFinishLaunchingWithOptions 回调中创建蓝牙服务到我的 AppDelegate

或者使用应该工作但不能工作的串行队列

当需要发送一些数据时,我使用其中之一

如果我只是不停地调用这个 writeValue 而没有尝试检查它是否可以安全地发送数据。它最终会失败。

使用此代码建立连接后,请求额外的后台执行时间

对此的任何想法或关于我如何给 CBCentralManager 一个不在 UI 线程上并且在应用程序进入后台时不会被关闭的队列的建议将不胜感激。如果那不可能,我需要尝试选择一种解决方法。

0 投票
1 回答
832 浏览

swift - 为什么我应该使用 NSManagedObjectContext 的 perform() 和 performAndWait() 而我可以使用 DispatchQueue.global

我对在后台队列上运行 CoreData 代码有些困惑。

我们可以使用一些方法来使用 NSManagedObjectContext 在后台线程上执行 CoreData 代码。

我在这里的问题是为什么我应该使用这些函数而不是使用普通方式使用 DispatchQueue 在后台线程上运行一些代码

0 投票
1 回答
374 浏览

swift - 如何仅在一个线程上运行任务?

假设我有几个数据库写入闭包,我想在单个线程上执行它们,但不是作为批处理 - 我需要在每次写入后更新 UI。

串行队列如:

或者

在他们想要运行的任何线程中运行,尽管是串行的。

我怎样才能有一个只在一个后台线程上运行的队列?