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

标签 swift animation loading background-thread

我在 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/

相关文章:

ios - 如何在 iOS 存储设置中显示下载的视频

jquery - 使用 CSS3/JS 的 SVG 径向删除动画

javascript - 基于多个 ScrollView(s) 为单个 View 设置动画

延迟加载后 jQuery 淡入图像

javascript - jQuery fullPage : All images loading at same time

ios - 从字符串中删除单词数组

ios - Swift:滚动不起作用

swift - 用于创建类实例或创建空变量的 If/Switch 语句

iphone - 如何调试 iPhone 应用程序崩溃日志。仅在 App Store 购买版本中崩溃,在开发中不会崩溃

R 警告 : "' package:stats' may not be available when loading"