我在制定问题标题时遇到了一些问题,如果您有更好的选择,请进行编辑。
我有一个登录过程,我添加了一个超时:
private func startTimeout() {
self.timeoutActive = true
DispatchQueue.main.asyncAfter(deadline: .now() + 20) {
[weak self] in
guard let weakSelf = self else {
return
}
if weakSelf.timeoutActive && !weakSelf.loggedIn {
weakSelf.onError("Login timed out")
}
}
}
我已经设计了Login过程,以便如果我们因任何原因需要再次登录(例如在注销后,或者在登录过程确定缺少或错误的凭据之后),我们最终会在同一个实例中执行登录的类。
现在,据我所知,我们永远不能阻止执行调度块,只能通过使用一些标志来阻止它,这是我对timeoutActive标志所做的。这就像一个魅力。
但是,如果第二个Login完全定时,以便在新的Login进程启动后执行Previous调度块,则会遇到问题(当启动新的登录过程时,timeoutActive标志再次设置为true) 。新的Login收到一个不正确的超时。
我一直在考虑不同的方法来解决它,并尝试了一些,但无法让它们中的任何一个起作用。
我有一个想法是使用performSelectorAfterDelay
而不是GCD,这是可取消的,但在Swift(3)中不可用。
我还想到了一些带有阻止块ID列表的唯一块ID - 但它看起来有些过分。
我也想过将块中的当前调度时间(.now())与原始截止时间(.now()+ 20)进行比较并查看它是否匹配,但我不知道这有多精确截止日期是,感觉不稳定。
我唯一的想法就是在Login过程中创建一些类似于Task的对象,并包含超时并为不同的Logins创建该任务的新实例。看起来像是一些工作,如果我找到一种更简单的方法,我更愿意。
之前是否有人遇到过此类情况并有解决方案?
答案 0 :(得分:0)
所以这就是我对Dan对该问题的评论所做的:
HAL_TIM_Base_Start(&htim7);
HAL_DAC_Start(&hdac1,DAC_CHANNEL_2);
HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_2, (uint32_t*)val, 64, DAC_ALIGN_12B_R);
离开ViewController或完成流程时使用private var timeoutBlock: DispatchWorkItem? = nil
private func startTimeout() {
self.timeoutBlock = DispatchWorkItem(block: { [weak self] in
guard let weakSelf = self else {
return
}
if !weakSelf.loggedIn {
weakSelf.onError("Login timed out")
}
})
DispatchQueue.main.asyncAfter(wallDeadline: .now() + 20, execute: self.timeoutBlock!)
}
。这按预期工作!