如何在特定时间戳后终止完成处理程序
Posted
技术标签:
【中文标题】如何在特定时间戳后终止完成处理程序【英文标题】:How to kill a completion handler after a specific timestamp 【发布时间】:2018-01-24 13:03:27 【问题描述】:我已经在按钮操作中编写了完成处理程序,就像下面的代码一样。
func backgroundTask(arg: Bool, completion: (Bool) -> ())
completion(arg)
在我的按钮中点击
backgroundTask(arg: true, completion: (success) -> Void in
if success
print("true")
else
print("false")
)
当用户多次按下按钮时,完成处理程序会返回那么多时间。
需要多次返回完成处理程序。
我需要打一个时间戳,之后完成处理程序不需要返回。
【问题讨论】:
我们需要知道您是如何执行后台任务的。 如果我正确理解了您的问题,您可以通过将其设为可选... completion: ((Bool) -> ())? )
并在适当时将其设置为 nil
来终止完成处理程序。但我不确定您的具体情况以及它如何适合您的应用程序。
【参考方案1】:
您不能简单地取消关闭。您可以做的是创建一个包含函数调用的DispatchWorkItem
,然后您可以取消工作项。与其简单地调用backgroundTask
,不如在用户每次按下按钮时创建DispatchWorkItem
,在项目上调用perform
,如果截止日期已过,则调用取消。
自给自足的游乐场示例:
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
func backgroundTask(arg: Bool, completion: (Bool) -> ())
completion(arg)
backgroundTask(arg: true, completion: (success) -> Void in
if success
print("true")
else
print("false")
)
let workItem = DispatchWorkItem(block: backgroundTask(arg: true, completion:
(success) -> Void in
if success
print("true")
DispatchQueue.main.asyncAfter(deadline: .now()+2, execute:
print("Delayed success") //As long as the deadline is smaller than the deadline of `workItem.cancel()`, this will be printed
)
else
print("false")
))
workItem.perform()
DispatchQueue.main.asyncAfter(deadline: .now()+3, execute:
workItem.cancel()
PlaygroundPage.current.finishExecution()
)
【讨论】:
【参考方案2】:如果我理解正确,看看这是否有效:
import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
let completionCancelDeadline: TimeInterval = 2.5
class Worker
init()
private var completion: ((Bool) -> ())?
func backgroundTask(arg: Bool, completion: ((Bool) -> ())?)
self.completion = completion
DispatchQueue.main.asyncAfter(deadline: .now() + completionCancelDeadline)
self.completion = nil
worker(arg: arg)
private func worker(arg: Bool)
let randomTaskDuration = TimeInterval(arc4random_uniform(5))
// randomTaskDuration is to simulate how long it's going to take the background task to complete
// and if it completes later than the completionCancelDeadline then the completion will be nil
DispatchQueue.main.asyncAfter(deadline: .now() + randomTaskDuration)
print("Time the background task took: \(randomTaskDuration) second(s)")
print("Should the completion exist: \(randomTaskDuration < completionCancelDeadline)")
self.completion?(arg)
print("") // Adding a new line intentionally to separate each call
class ViewController: UIViewController
func buttonTap()
let worker = Worker()
worker.backgroundTask(arg: true) success in
print("Completion called")
let vc = ViewController()
vc.buttonTap()
vc.buttonTap()
vc.buttonTap()
vc.buttonTap()
【讨论】:
以上是关于如何在特定时间戳后终止完成处理程序的主要内容,如果未能解决你的问题,请参考以下文章