WeakSynchronizedDelegate.swift 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //
  2. // WeakSynchronizedDelegate.swift
  3. // LoopKit
  4. //
  5. // Copyright © 2019 LoopKit Authors. All rights reserved.
  6. //
  7. import Foundation
  8. public class WeakSynchronizedDelegate<Delegate> {
  9. private let lock = UnfairLock()
  10. private weak var _delegate: AnyObject?
  11. private var _queue: DispatchQueue
  12. public init(queue: DispatchQueue = .main) {
  13. _queue = queue
  14. }
  15. public var delegate: Delegate? {
  16. get {
  17. return lock.withLock {
  18. return _delegate as? Delegate
  19. }
  20. }
  21. set {
  22. lock.withLock {
  23. _delegate = newValue as AnyObject
  24. }
  25. }
  26. }
  27. public var queue: DispatchQueue! {
  28. get {
  29. return lock.withLock {
  30. return _queue
  31. }
  32. }
  33. set {
  34. lock.withLock {
  35. _queue = newValue ?? .main
  36. }
  37. }
  38. }
  39. public func notify(_ block: @escaping (_ delegate: Delegate?) -> Void) {
  40. var delegate: Delegate?
  41. var queue: DispatchQueue!
  42. lock.withLock {
  43. delegate = _delegate as? Delegate
  44. queue = _queue
  45. }
  46. queue.async {
  47. block(delegate)
  48. }
  49. }
  50. public func notifyDelayed(by interval: TimeInterval, _ block: @escaping (_ delegate: Delegate?) -> Void) {
  51. var delegate: Delegate?
  52. var queue: DispatchQueue!
  53. lock.withLock {
  54. delegate = _delegate as? Delegate
  55. queue = _queue
  56. }
  57. queue.asyncAfter(deadline: .now() + interval) {
  58. block(delegate)
  59. }
  60. }
  61. public func call<ReturnType>(_ block: (_ delegate: Delegate?) -> ReturnType) -> ReturnType {
  62. return lock.withLock { () -> ReturnType in
  63. var result: ReturnType!
  64. _queue.sync {
  65. result = block(_delegate as? Delegate)
  66. }
  67. return result
  68. }
  69. }
  70. }