我想在一个事件的10秒内运行一段代码,但是我希望能够取消它,这样如果在那10秒之前发生了某些事情,代码将在10秒后不再运行.
我一直在使用它,但它不可取消:
static func delay(delay:Double, closure:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(delay * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), closure
)
}
Run Code Online (Sandbox Code Playgroud)
我怎么能做到这一点?
Dav*_*son 222
Swift 3有DispatchWorkItem:
let task = DispatchWorkItem { print("do something") }
// execute task in 2 seconds
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2, execute: task)
// optional: cancel task
task.cancel()
Run Code Online (Sandbox Code Playgroud)
Sau*_*hah 20
Swift 3.0的更新
设置执行选择器
perform(#selector(foo), with: nil, afterDelay: 2)
Run Code Online (Sandbox Code Playgroud)
foo方法将在2秒后调用
func foo()
{
//do something
}
Run Code Online (Sandbox Code Playgroud)
取消待处理的方法调用
NSObject.cancelPreviousPerformRequests(withTarget: self)
Run Code Online (Sandbox Code Playgroud)
sas*_*sas 12
试试这个(Swift 2.x,请参阅下面的David对Swift 3的回答):
typealias dispatch_cancelable_closure = (cancel : Bool) -> ()
func delay(time:NSTimeInterval, closure:()->()) -> dispatch_cancelable_closure? {
func dispatch_later(clsr:()->()) {
dispatch_after(
dispatch_time(
DISPATCH_TIME_NOW,
Int64(time * Double(NSEC_PER_SEC))
),
dispatch_get_main_queue(), clsr)
}
var closure:dispatch_block_t? = closure
var cancelableClosure:dispatch_cancelable_closure?
let delayedClosure:dispatch_cancelable_closure = { cancel in
if let clsr = closure {
if (cancel == false) {
dispatch_async(dispatch_get_main_queue(), clsr);
}
}
closure = nil
cancelableClosure = nil
}
cancelableClosure = delayedClosure
dispatch_later {
if let delayedClosure = cancelableClosure {
delayedClosure(cancel: false)
}
}
return cancelableClosure;
}
func cancel_delay(closure:dispatch_cancelable_closure?) {
if closure != nil {
closure!(cancel: true)
}
}
// usage
let retVal = delay(2.0) {
println("Later")
}
delay(1.0) {
cancel_delay(retVal)
}
Run Code Online (Sandbox Code Playgroud)
来自Waam的评论:dispatch_after - GCD in swift?
你需要这样做:
class WorkItem {
private var pendingRequestWorkItem: DispatchWorkItem?
func perform(after: TimeInterval, _ block: @escaping VoidBlock) {
// Cancel the currently pending item
pendingRequestWorkItem?.cancel()
// Wrap our request in a work item
let requestWorkItem = DispatchWorkItem(block: block)
pendingRequestWorkItem = requestWorkItem
DispatchQueue.main.asyncAfter(deadline: .now() + after, execute:
requestWorkItem)
}
}
// to use
lazy var workItem = WorkItem()
private func onMapIdle() {
workItem.perform(after: 1.0) {
self.handlePOIListingSearch()
}
}
Run Code Online (Sandbox Code Playgroud)
参考
| 归档时间: |
|
| 查看次数: |
15782 次 |
| 最近记录: |