ios - DispatchQueue.main.asyncAfter 带开/关开关
问题描述
我创建了以下结构,以在网络连接速度慢时提醒用户。
当一个函数要调用服务器时,它会创建一个 ResponseTimer。这会设置延迟通知,仅当 responseTimer var isOn = true 时才会触发。当我的函数得到来自服务器的响应时,设置 responseTimer.isOn = false。
这是结构:
struct ResponseTimer {
var isOn: Bool
init() {
self.isOn = true
self.setDelayedAlert()
}
func setDelayedAlert() {
let timer = DispatchTime.now() + 8
DispatchQueue.main.asyncAfter(deadline: timer) {
if self.isOn {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: toastErrorNotificationKey), object: self, userInfo: ["toastErrorCase" : ToastErrorCase.poorConnection])
}
}
}
这就是我如何使用它
func getSomethingFromFirebase() {
var responseTimer = ResponseTimer()
ref.observeSingleEvent(of: .value, with: { snapshot in
responseTimer.isOn = false
//do other stuff
})
}
即使在 8 秒延迟完成之前响应返回的情况下,仍会触发通知。我在这里做错了什么???有没有更好的模式可以用于这样的事情?
谢谢您的帮助!
解决方案
更好的方法是使用DispatchSourceTimer
可以取消的
var timer : DispatchSourceTimer?
func startTimer()
{
if timer == nil {
timer = DispatchSource.makeTimerSource(queue: DispatchQueue.global())
timer!.schedule(deadline: .now() + .seconds(8))
timer!.setEventHandler {
DispatchQueue.main.async {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: toastErrorNotificationKey), object: self, userInfo: ["toastErrorCase" : ToastErrorCase.poorConnection])
}
self.timer = nil
}
timer!.resume()
}
}
func getSomethingFromFirebase() {
startTimer()
ref.observeSingleEvent(of: .value, with: { snapshot in
self.timer?.cancel()
self.timer = nil
//do other stuff
})
}
推荐阅读
- angularjs - 如何从规范文件中引用单个 HTML 文件中定义的 AngularJS 模块
- keras - 条件变分自编码器理解
- java - 当 API 引入新的异常类型时编写向前兼容的代码
- c++ - 从 C++ 中的 txt 文件中读取数字行
- sql - SQL 循环和连接
- mysql - 如何根据 MySQL 或 node.js 中的相同值对结果进行分组
- java - com.akamai.edgegrid.signer 无法解决
- android - Android 模拟器的 Socket 可以工作,但不能用于真实设备
- java - 在我的应用程序中发送图像消息时遇到困难并遇到错误。短信工作正常
- c# - 如何在 CallBimlScript 中解决“无法转换类型为 'System.String' 的对象”