“等一秒钟”:为什么Swift中的延迟是魔法,而不是技巧
\n\n想象一下:您正在编写一个披萨订购应用。用户点击“支付”,瞬间——砰!——钱被扣了。没有动画,没有暂停,没有“正在发生某事”的感觉。用户吓坏了,关闭应用,您就失去了客户。Swift中的延迟不是拐杖,而是UX设计和正确架构的工具。
\n\n“How to create a delay in Swift?”这个问题在Stack Overflow上获得了数万次浏览。这并不奇怪:新手试图使用sleep()(剧透:不能这样做),而专业人士则寻找优雅的解决方案。我们将分析5种可行的方法——从经典的GCD到现代的async/await。开始吧!
1. 经典方法:DispatchQueue.main.asyncAfter (iOS 4+)
\n在Swift中创建延迟最流行的方法是DispatchQueue.main.asyncAfter。它适用于任何iOS版本,无需额外导入。适合在主线程上执行代码(例如,更新UI)。
import UIKit\n\nclass ViewController: UIViewController {\n override func viewDidLoad() {\n super.viewDidLoad()\n \n // 延迟2秒\n DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {\n print("2秒过去了!")\n self.showAlert()\n }\n }\n \n func showAlert() {\n let alert = UIAlertController(title: "你好!", message: "这是延迟", preferredStyle: .alert)\n alert.addAction(UIAlertAction(title: "确定", style: .default))\n present(alert, animated: true)\n }\n}\n\n优点和缺点
\n- \n
- 优点:简单,向后兼容,在主线程上工作。 \n
- 缺点:无法取消延迟(除非保存DispatchWorkItem)。 \n
2. 通过DispatchWorkItem实现可取消的延迟
\n有时需要取消延迟——例如,用户离开了屏幕。DispatchWorkItem解决了这个问题。保存对“任务”的引用并调用cancel()。
class DelayedTask {\n private var workItem: DispatchWorkItem?\n \n func scheduleDelayedAction() {\n // 创建任务\n let item = DispatchWorkItem { [weak self] in\n print("任务在延迟后执行")\n self?.doSomething()\n }\n \n // 保存并启动\n workItem = item\n DispatchQueue.main.asyncAfter(deadline: .now() + 3.0, execute: item)\n }\n \n func cancelDelayedAction() {\n workItem?.cancel()\n workItem = nil\n print("任务已取消")\n }\n \n func doSomething() {\n // 您的代码\n }\n}\n\n// 使用\nlet task = DelayedTask()\ntask.scheduleDelayedAction()\n// 1秒后取消\nDispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {\n task.cancelDelayedAction()\n}\n\n请注意[weak self]——这是必须的,以避免Swift中的内存泄漏。如果不弱化引用,延迟可能会比控制器存活得更久。
3. Timer.scheduledTimer:带重复的延迟
\nSwift定时器不仅仅是用于重复任务。可以创建一个带延迟的一次性定时器。优点:定时器易于取消,并且可以暂停。
\n\nclass TimerExample {\n var timer: Timer?\n \n func startDelayedAction() {\n // 1.5秒后的一次性定时器\n timer = Timer.scheduledTimer(withTimeInterval: 1.5, repeats: false) { [weak self] _ in\n print("定时器在1.5秒后触发")\n self?.updateUI()\n }\n }\n \n func stopTimer() {\n timer?.invalidate()\n timer = nil\n }\n \n func updateUI() {\n // 更新界面\n }\n}\n\n何时使用Timer
\n- \n