gpt4 book ai didi

Swift:运行代码会阻止其他代码直到完成

转载 作者:行者123 更新时间:2023-11-28 11:56:28 25 4
gpt4 key购买 nike

我在 ViewDidAppear 中调用一个动画,稍后在 ViewDidAppear 中我调用一个创建多个 UIImage 对象数组并需要 4-5 秒的函数完成。

同时,动画只有 0.8 秒长,并且有一个完成 block :

UIView.animate(withDuration: 0.8, delay: 0.0, options: UIViewAnimationOptions(), animations: {
self.myView.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
}, completion: { finished in
self.nextTask()
})

问题是完成 block 不会在 0.8 秒后运行 - 它直到前面的代码完成后才运行。

除了 在后台线程中使用 DispatchQueue.global(qos: .background).async 运行该代码,我还有什么可以做的吗?或者有没有办法提高后台线程的完成速度?

如果在后台线程中完成,我的动画不会中断,但在后台完成需要更长的时间 - 大约 20-30 秒而不是 4-5 秒。

感谢您在这里分享的任何帮助!

最佳答案

I am calling a function which creates several arrays of UIImage objects and takes 4-5 seconds to complete

你绝对不能在主线程上运行它。现代设备上的刷新帧为 1/120 秒。您不得导致帧丢失。发生这种情况时,您正在阻止用户交互。屏幕将被卡住,看门狗进程将当场杀死您的应用程序。 (不幸的是,模拟器没有向您显示,也没有从设备上的 Xcode 运行;但是如果您在设备上运行应用程序,请停止它,然后从设备而不是从 Xcode 运行它,你会明白我的意思。)

The issue is that the completion block doesn't run 0.8 seconds later - it doesn't run until AFTER the previous code completes.

正如您所猜测的,这里存在重入问题。您需要离开主线程以允许完成 block 发生。我真的很惊讶动画甚至开始(是吗?)。当您仍在主线程上运行代码时,什么都不会发生。

您可以调用 async_after 并短暂延迟以暂时跳出主线程,然后重新进入主线程,足够长的时间让刷新帧发生,这样系统就可以做一些工作。但这只是让动画开始的一种方式。一旦您回到主线程,您将再次阻塞它。

至于速度:.background 的 QOS 是最慢的选择,因此您得到了您想要的。不过,一般来说,不要使用全局队列;制作自己的队列。我无法想象你正在做的事情会花这么长时间,也许这才是你真正应该问的问题,但你绝对不能在主线程上做。

关于Swift:运行代码会阻止其他代码直到完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50884634/

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