代码之家  ›  专栏  ›  技术社区  ›  RanLearns

swift:运行代码在完成之前阻止其他代码

  •  0
  • RanLearns  · 技术社区  · 7 年前

    我在叫动画 ViewDidAppear ,然后稍后 视图显示 我正在调用一个函数,该函数创建几个uiimage对象数组,需要4-5秒才能完成。

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

    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()
            })
    

    问题是,完成块在0.8秒后才运行—直到前一个代码完成后才运行。

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

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

    感谢您在这里提供的帮助!

    1 回复  |  直到 7 年前
        1
  •  2
  •   matt    7 年前

    我正在调用一个函数,该函数创建多个uiimage对象数组,需要4-5秒才能完成

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

    问题是,完成块在0.8秒后才运行—直到前一个代码完成后才运行。

    正如你所猜测的,这里有一个重新进入的问题。您需要离开主线程,以允许完成块发生。我真的很惊讶动画 开始 (是吗?)。在主线程上运行代码时,根本不会发生任何事情。

    你可以打电话 async_after 用很短的延迟从主线程上跳下,然后重新进入它,足够长的时间让刷新帧发生,这样系统就可以做一些工作。但那只是让动画开始的一种方式。一旦你回到主线,你会再次阻塞它。

    至于速度:QoS .background 最慢的 选择,所以你得到了你想要的。不过,一般情况下,不要使用全局队列;创建自己的队列。我无法想象你在做什么会花这么长时间,也许这才是你真正应该问的,但你绝对不能在主线上做。