Lifetime.swift 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. import Foundation
  2. import enum Result.NoError
  3. /// Represents the lifetime of an object, and provides a hook to observe when
  4. /// the object deinitializes.
  5. public final class Lifetime {
  6. /// MARK: Type properties and methods
  7. /// A `Lifetime` that has already ended.
  8. public static var empty: Lifetime {
  9. return Lifetime(ended: .empty)
  10. }
  11. /// MARK: Instance properties
  12. /// A signal that sends a `completed` event when the lifetime ends.
  13. public let ended: Signal<(), NoError>
  14. /// MARK: Initializers
  15. /// Initialize a `Lifetime` object with the supplied ended signal.
  16. ///
  17. /// - parameters:
  18. /// - signal: The ended signal.
  19. private init(ended signal: Signal<(), NoError>) {
  20. ended = signal
  21. }
  22. /// Initialize a `Lifetime` from a lifetime token, which is expected to be
  23. /// associated with an object.
  24. ///
  25. /// - important: The resulting lifetime object does not retain the lifetime
  26. /// token.
  27. ///
  28. /// - parameters:
  29. /// - token: A lifetime token for detecting the deinitialization of the
  30. /// associated object.
  31. public convenience init(_ token: Token) {
  32. self.init(ended: token.ended)
  33. }
  34. /// A token object which completes its signal when it deinitializes.
  35. ///
  36. /// It is generally used in conjuncion with `Lifetime` as a private
  37. /// deinitialization trigger.
  38. ///
  39. /// ```
  40. /// class MyController {
  41. /// private let token = Lifetime.Token()
  42. /// public var lifetime: Lifetime {
  43. /// return Lifetime(token)
  44. /// }
  45. /// }
  46. /// ```
  47. public final class Token {
  48. /// A signal that sends a Completed event when the lifetime ends.
  49. fileprivate let ended: Signal<(), NoError>
  50. private let endedObserver: Signal<(), NoError>.Observer
  51. public init() {
  52. (ended, endedObserver) = Signal.pipe()
  53. }
  54. deinit {
  55. endedObserver.sendCompleted()
  56. }
  57. }
  58. }