Skip to content

Instantly share code, notes, and snippets.

@natanrolnik
Created February 8, 2019 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save natanrolnik/4362cba58e596d8c2256df751a909067 to your computer and use it in GitHub Desktop.
Save natanrolnik/4362cba58e596d8c2256df751a909067 to your computer and use it in GitHub Desktop.
Another small wrapper for multiple DispatchWorkItems
PlaygroundPage.current.needsIndefiniteExecution = true
typealias DispatcherIdentifier = String
extension DispatchQueue {
static var associatedValueKey = 0
func schedule(after timeInterval: TimeInterval,
with identifier: DispatcherIdentifier,
action: @escaping () -> Void) {
var items =
objc_getAssociatedObject(self, &DispatchQueue.associatedValueKey) as? [DispatcherIdentifier: DispatchWorkItem]
?? [:]
cancelAction(with: identifier)
print("Scheduled \(identifier)")
let item = DispatchWorkItem(block: action)
items[identifier] = item
objc_setAssociatedObject(self, &DispatchQueue.associatedValueKey, items, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
self.asyncAfter(deadline: .now() + timeInterval, execute: item)
}
@discardableResult
func cancelAction(with identifier: DispatcherIdentifier) -> Bool {
guard
var items = objc_getAssociatedObject(self, &DispatchQueue.associatedValueKey) as? [DispatcherIdentifier: DispatchWorkItem],
let item = items[identifier]
else {
return false
}
defer {
objc_setAssociatedObject(self, &DispatchQueue.associatedValueKey, items, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
guard !item.isCancelled else {
items[identifier] = nil
return false
}
item.cancel()
print("Cancelled \(identifier)")
return true
}
}
let dispatcher = DispatchQueue.main
dispatcher.schedule(after: 2, with: "first") {
print("---> Hey, I'm first")
}
dispatcher.schedule(after: 3, with: "first") {
print("---> No dude, I'm first")
}
dispatcher.schedule(after: 4, with: "second") {
print("---> I'm second, but I'll be cancelled")
}
dispatcher.schedule(after: 5, with: "third") {
print("---> And I'm third")
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
dispatcher.cancelAction(with: "second")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment