gpt4 book ai didi

swift - 在 Swift 中调度两个独立的异步线程

转载 作者:搜寻专家 更新时间:2023-10-31 23:09:42 27 4
gpt4 key购买 nike

我正在尝试加载一组按钮,这些按钮将在加载菜单时一个接一个地滑入。所以我这样做了:

    buttonTimer = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(MainMenu.enterButtons), userInfo: nil, repeats: true)
buttonTimer.fire()

这将运行 enterButtons() 方法,该方法将运行按钮的移动 Action 。这个计时器是在这个菜单的初始化过程中创建的,因为我希望按钮在初始化时加载。然而,在我的初始化过程中,我还初始化了一个性能很重的类,因为它包含我所有的级别:

    DispatchQueue.main.asyncAfter(deadline: .now()) {
self.initialLevel.levelHolder = LevelHolder(screenWidth: Float(self.initialLevel.size.width), scene: self.initialLevel, screenSize: self.initialLevel.frame, initialLevel: (1,1))
}

所以我以异步方式执行此操作,因为如果我不这样做,它将阻止初始化程序的所有其他功能。但是,我认为这两个线程实际上只是一个线程。异步任务的顺序是:

  1. 初始化级别持有者
  2. 加载按钮

我希望这两个任务能同时运行。然而,似乎我希望的不是三个线程(主线程,一个用于关卡持有者,一个用于加载按钮)我相信只有两个:主线程和一个用于我创建的两个异步任务.在我的调试 session 期间,我注意到加载按钮任务等待级别持有者被初始化。但是,我想创建三个独立的异步线程。我该怎么做?

编辑

我尝试为关卡持有者实现并发我试过这个,@UpholderOfTruth 建议:

    DispatchQueue.global(qos: .background) {
self.initialLevel.levelHolder = LevelHolder(screenWidth: Float(self.initialLevel.size.width), scene: self.initialLevel, screenSize: self.initialLevel.frame, initialLevel: (1,1))
}

但我收到一条错误消息:

LevelHolder is not convertible to 'LevelHolder!'

因为 self.initialLevel.levelHolder 是 LevelHolder 类型!但我将其设置为等于 LevelHolder。

我怎样才能避免这个错误?我试过这样做:

self.initialLevel.levelHolder = LevelHolder(screenWidth: Float(self.initialLevel.size.width), scene: self.initialLevel, screenSize: self.initialLevel.frame, initialLevel: (1,1))!

但是 Xcode 会提示警告我

cannot force unwrap to a non-optional type 'LevelHolder'

initialLevel 在初始化关卡持有者的方法中被初始化:

func initializeLevelHolder() {
initialLevel = InitialLevel()
initialLevel.size = self.size
DispatchQueue.main.asyncAfter(deadline: .now()) {
self.initialLevel.levelHolder = LevelHolder(screenWidth: Float(self.initialLevel.size.width), scene: self.initialLevel, screenSize: self.initialLevel.frame, initialLevel: (1,1))
}
}

它是这个菜单的一个实例变量,定义为

var initialLevel : InitialLevel!

最佳答案

您立即将 levelHolder 代码推回主线程,并将按钮时间设置为在 0.1 秒后触发,然后在方法完成后手动触发它。所以一切都在主线程上发生,你的 levelHolder 处理阻止了按钮处理。

您可以像这样将 levelHolder 处理放到后台线程上:

DispatchQueue.global(qos: .background).async {
self.initialLevel.levelHolder = LevelHolder(screenWidth: Float(self.initialLevel.size.width), scene: self.initialLevel, screenSize: self.initialLevel.frame, initialLevel: (1,1))
}

但是不要忘记对 UI 的任何更新仍然需要像这样返回主线程:

DispatchQueue.main.async {
// Update the UI
}

不幸的是,对此我们无能为力,因为所有 UI 更新都必须在主线程上进行,因此会在一定程度上相互阻塞。

关于swift - 在 Swift 中调度两个独立的异步线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44468706/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com