Swift 如何在特定时间戳后终止完成处理程序
我已经在按钮操作中编写了完成处理程序,如下代码所示Swift 如何在特定时间戳后终止完成处理程序,swift,background-process,completionhandler,Swift,Background Process,Completionhandler,我已经在按钮操作中编写了完成处理程序,如下代码所示 func backgroundTask(arg: Bool, completion: (Bool) -> ()) { completion(arg) } 在我的按钮点击 backgroundTask(arg: true, completion: { (success) -> Void in if success { print("true") } else { pr
func backgroundTask(arg: Bool, completion: (Bool) -> ()) {
completion(arg)
}
在我的按钮点击
backgroundTask(arg: true, completion: { (success) -> Void in
if success {
print("true")
} else {
print("false")
}
})
当用户多次按下按钮时,完成处理程序返回的时间就相当长
需要多次返回完成处理程序
我需要设置一个时间戳,之后完成处理程序不需要返回。您不能简单地取消关闭。您可以改为创建一个包含函数调用的DispatchWorkItem,然后取消该工作项。与简单调用backgroundTask不同,您应该在用户每次按下按钮时创建DispatchWorkItem,在项目上调用perform,如果截止日期已过,则调用cancel 独立操场示例:
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()
})
您不能简单地取消关闭。您可以改为创建一个包含函数调用的DispatchWorkItem,然后取消该工作项。与简单调用backgroundTask不同,您应该在用户每次按下按钮时创建DispatchWorkItem,在项目上调用perform,如果截止日期已过,则调用cancel 独立操场示例:
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()
})
如果我理解正确,看看这是否有效:
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()
如果我理解正确,看看这是否有效:
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()
我们需要知道你是如何执行后台任务的。如果我正确理解了你的问题,你可以通过将其设置为可选来杀死一个完成处理程序。。。完成:Bool->?在合适的时候把它设为零。但我不确定您的具体情况以及它如何适合您的应用程序。我们需要知道您如何执行后台任务。如果我正确理解您的问题,您可以通过将其设置为可选来杀死完成处理程序。。。完成:Bool->?在合适的时候把它设为零。但我不确定你的具体情况以及它如何适合你的应用程序。