Cancellable.swift 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. /// Will run a 'cancel' action when the cancellable falls out of scope (gets
  2. /// deinited by ARC). Protects against calling the action twice.
  3. public class Cancellable {
  4. /// The cancel action to call on deinit.
  5. private var closure: (() -> Void)?
  6. /// A human-readable tag for debugging purposes.
  7. var tag: String?
  8. /// If defused, the cancellable won't cancel the ongoing action on deinit.
  9. var defused = false
  10. /// Creates a new cancellable.
  11. ///
  12. /// - Parameter closure: The closure to call when this cancellable falls out
  13. /// of scope (i.e. is deinited).
  14. public init(closure: @escaping () -> Void) {
  15. self.closure = closure
  16. }
  17. /// Prevents the cancellable from calling its cancel action when it goes out
  18. /// of scope.
  19. func defuse() {
  20. defused = true
  21. }
  22. /// Runs the cancel action.
  23. deinit {
  24. if !defused {
  25. cancel()
  26. }
  27. }
  28. /// Runs the cancel action and ensures that it can't be called a second
  29. /// time.
  30. public func cancel() {
  31. closure?()
  32. closure = nil
  33. }
  34. /// Adds a human-readable tag to the cancellable.
  35. ///
  36. /// This method is a no-op in release mode.
  37. ///
  38. /// - Parameter tag: The tag to add.
  39. @discardableResult
  40. func tag(with tag: @autoclosure () -> String?) -> Self {
  41. #if DEBUG
  42. self.tag = tag()
  43. #endif
  44. return self
  45. }
  46. }