GCD 是一种非常方便的使用多线程的方式。通过使用GCD,我们可以在确保语法尽量简单的前提下进行灵活的多线程编程。在“复杂必死”的多线程编程中,保持简单就是避免错误的金科玉律。好消息是在Swift 中是可以无缝使用GCD 的API 的,而且得益于闭包特性的加入,使用起来比之前在Objective-C 中更加简单方便。在这里我不打算花费很多时间介绍GCD 的语法和要素,否则就可以专门为GCD 写上一节了。下面给出了一个日常生活中最常使用的例子(说这个例子能覆盖到日常GCD 使用的50% 以上也不为过),来展示一下Swift 里的GCD 调用会是什么样子:

let workingQueue = DispatchQueue.init(label: "my_queue")
workingQueue.async {// 在 workingQueue 中异步进行print("努力学习")Thread.sleep(forTimeInterval: 2) // 模拟两秒的执行时间DispatchQueue.main.async {// 返回到主线程更新UIprint("结束学习,更新UI")}
}

因为UIKit 是只能在主线程工作的,如果主线程的工作过于繁重的话,就会导致App 出现“卡死”的现象:UI 不能更新,用户输入无法响应等等,这是非常糟糕的用户体验。为了避免这种情况的出现,对于繁重的(如图像加滤镜等)或者很长时间才能完成的(如从网络下载图片)任务,我们应该把它们放到后台线程进行,这样在用户看来UI 还是可以交互的,也不会出现卡顿。在工作进行完成后,我们需要更新UI 的话,必须回到主线程进行(要牢记和UI 相关的工作都需要在主线程执行,否则可能发生不可预知的错误)。

在日常的开发工作中,我们经常会遇到这样的需求:在若干秒后执行某个方法。比如切换界面 2秒后开始播一个动画,或者提示框出现 3秒后自动消失等等。以前在Objective-C 中,我们可以使用一个NSObject 的实例方法 - (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay 来指定在一定时间后执行某个Selector。不过如果你现在新建一个Swift 的项目,并且试图使用这个方法(或者这个方法的其他一切变形)的话,会发现这个方法已经不见了!

发生什么了?因为我们强调过很多次,Swift 的一大追求就是安全两个字,但是原来的performSelector: 这套东西在ARC 下并不安全的。因为ARC 为了确保参数在方法运行期间的存在,会将输入参数在方法开始时先进行retain,然后在最后release。而对于performSelector: 这个方法我们并没有机会为被调用的方法指定参数,于是被调用的selector的输入有可能指向未知垃圾内存地址,然后… 更要命的是这种崩溃不能每次重现

但无论如何都想继续做延时调用的话,我们该怎么办呢?最容易想到的是使用Timer 来创建一个若干秒后调用一次的计时器。但是这么做我们需要创建新的对象,和一个本来不相干的Timer 类扯上关系,同时也会用到Objective-C 的运行时特性去查找方法等,总觉着有点笨。其实GCD 里有一个很好用的延时调用,我们可以加以利用写出很漂亮的方法来,那就是after。最简单的使用方法看起来是这样的:

let time: TimeInterval = 2.0
let delay = DispatchTime.init(uptimeNanoseconds: DispatchTime.now() + time)
DispatchQueue.main.asyncAfter(deadline: delay) {print("2秒后输出")
}

代码非常简单,并没有什么值得详细说明的。只是每次写这么多的话也挺累的,在这里我们可以稍微将它封装的好用一些,最好再加上取消的功能。

import Foundationtypealias Task = (Bool) -> ()func delay(_ time: TimeInterval, task: @escaping () -> Void) -> Task? {func dispatchLater(block: @escaping () -> Void) {DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time, execute: block)}var closure: Dispatch.os_block_t? = taskvar result: Task?let delayedClosure: Task = { cancel inif let internalClosure = closure {if cancel == false {DispatchQueue.main.async(execute: internalClosure)}}closure = nilresult = nil}result = delayedClosuredispatchLater {if let delayedClosure = result {delayedClosure(false)}}return result
}func cancel(_ task: Task?) {task?(true)
}

使用的时候就很简单了,我们想在2秒以后干点儿什么的话,就这样做:

delay(2) {print("2秒后输出")
}

想要取消的话,我们可以先保留一个对Task 的引用,然后调用cancel:

let task = delay(5) {print("5秒后输出")
}// 立即取消
cancel(task)

Swift - GCD 和延时调用相关推荐

  1. swift 多线程GCD和延时调用

    GCD 是一种非常方便的使用多线程的方式.通过使用 GCD,我们可以在确保尽量简单的语法的前提下进行灵活的多线程编程.在 "复杂必死" 的多线程编程中,保持简单就是避免错误的金科玉 ...

  2. iOS Swift GCD 开发教程

    本教程将带你详细了解 GCD 的概念和用法,通过文中的代码示例和附带的 Github 示例工程,可以进一步加深对这些概念的体会.附带的示例工程是一个完整可运行的 App 项目:DispatchQueu ...

  3. Swift5多线程系列一GCD异步/延时使用初步封装

    Swift5多线程系列一GCD异步/延时使用初步封装 GCD异步延时使用初步目录 Swift5多线程系列一GCD异步/延时使用初步封装 前言 一.封装成基本的struct 二.基本使用 1.异步初步任 ...

  4. 一个class运用promise的延时调用

    使用prosmise链式调用可以实现延时调用的效果 class Person {constructor(name){this.name = name;this.queue = Promise.reso ...

  5. swift怎么调用Java,Swift完成UIAlertController的调用

    Swift完成UIAlertController的调用 iOS8中的UIAlertView和UIActionSheet已经都被UIAlertViewController代替了,所以,本篇blog就来探 ...

  6. 60-300-024-使用-延迟数据-Flink中延时调用设计与实现

    1.世界 2.概述 在电商商品购买过程中有这样一些场景:用户点击下单,此时订单处于待支付状态,如果在2小时之后还处于待支付状态那么就将这笔订单取消,置为取消状态:用户收货之后可以对商品进行评价,如果在 ...

  7. swift项目调用OC库 和OC项目 在swift文件里面全局调用OC库

    最近比较清闲,就把以前学习的过程记录下吧,多少年后如果能在互联网上找到自己的痕迹,想想还是一件蛮值得高兴的事情. 正好这两天加了一个swift学习群想继续学习swift,发现好多swift初学者,在混 ...

  8. js定时器和延时调用的使用

    javascript定时器使用 可以使用setInterval(回调函数,间隔时间)函数,定时调用一段程序 回调函数本质就是一个函数(有点废话),但它是JS帮我们调用的,所以叫回调函数. 间隔时长单位 ...

  9. JS中定时器和延时调用学习笔记

    JS中定时器和延时调用 在JS中希望一个函数重复的执行,可以为该函数设置一个定时装置 方法: setInterval(); 该方法可以将一个函数,每隔一段时间被调用一次 有两个参数 第一个是回调函数, ...

最新文章

  1. 开源即时通讯软件|最好的开源即时通讯软件——XEIM
  2. CTF中Crypty入门必看(密码类,密码学)
  3. 云资源管理有助于减少服务滥用和开支
  4. vue编程式导航,命名路由
  5. android app功能测试,androidAPP功能测试要点幻灯片.pptx
  6. vb教材笔记_vb学习笔记
  7. 倒车检测线怎么接图解_倒车影像摄像头3根线安装图解 这是倒车影像的电源线...
  8. 计算机word降序排列怎么做,怎么降序排列word
  9. 苹果电脑的文件怎么复制到移动硬盘,macbook文件怎么拷贝到移动硬盘
  10. 我喜欢的刀刀语录(一)
  11. 暴走英雄坛服务器维修,暴走英雄坛采集位置及注意事项一览
  12. 电信中兴光猫ZXHN F650超管密码获取工具
  13. 初中计算机会考多少字合格,初中初三期中考试总分应该是多少
  14. oracle标量子查询 外层,Oracle标量子查询
  15. 学习笔记17 --使用matlab自带函数,将旋转矩阵计算成欧拉角
  16. 【各版本通吃】【2023/05/14更新】通过网易云音乐分享链接找到分享用户主页
  17. 浪子心声-难分真与假人面多险诈
  18. JS变异小技巧:使用JavaScript全局变量绕过XSS过滤器
  19. 创意黑板粉笔字效果PPT模板
  20. 5G未来潜力所在-毫米波技术

热门文章

  1. 蓝桥杯 算法提高 卡勒沃夫之弱水路三千(提高型)
  2. 【费曼学习法】史上最强学习方法,无论是给自己还是给孩子,都非常值得尝试
  3. 如何高效工作,手把手教你制定自己的时间表-20200408(第1期)
  4. JS 获取当前日期时间/时间日期格式化(时间戳 转 yyyy-MM-dd HH:mm:ss)
  5. 什么是泊松分布?什么是泊松过程?
  6. 数百面试问题、覆盖AI核心主题,401页的深度学习面经免费下载了
  7. 基于遗传算法优化的BP神经网络
  8. 5.1 频率响应概述
  9. 色彩转换系列之RGB格式与HSV格式互转原理及实现
  10. 微信小程序商城如何搭建,低成本+高效率运营!