NSObject+Extension.swift 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. //
  2. // NSObject+Extension.swift
  3. // Lanu
  4. //
  5. // Created by OneeChan on 2025/11/14.
  6. //
  7. import Foundation
  8. import Combine
  9. private final class CancellableBagContainer {
  10. /// 线程安全的订阅容器
  11. var cancellables: Set<AnyCancellable> = []
  12. /// 读写锁(避免多线程操作Set崩溃)
  13. let lock = NSLock()
  14. }
  15. private var cancellableBagKey: UInt8 = 0
  16. extension NSObject {
  17. /// 用于存储Combine订阅的容器,自动与对象生命周期绑定
  18. var cancellables: Set<AnyCancellable> {
  19. get {
  20. // 先获取容器实例
  21. let container: CancellableBagContainer = {
  22. if let existing = objc_getAssociatedObject(self, &cancellableBagKey) as? CancellableBagContainer {
  23. return existing
  24. }
  25. let newContainer = CancellableBagContainer()
  26. objc_setAssociatedObject(self, &cancellableBagKey, newContainer, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
  27. return newContainer
  28. }()
  29. // 返回容器内的Set(拷贝,保证值语义)
  30. return container.cancellables
  31. }
  32. set {
  33. // 获取/创建容器,更新内部Set
  34. let container: CancellableBagContainer = {
  35. if let existing = objc_getAssociatedObject(self, &cancellableBagKey) as? CancellableBagContainer {
  36. return existing
  37. }
  38. let newContainer = CancellableBagContainer()
  39. objc_setAssociatedObject(self, &cancellableBagKey, newContainer, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
  40. return newContainer
  41. }()
  42. container.lock.lock()
  43. container.cancellables = newValue
  44. container.lock.unlock()
  45. }
  46. }
  47. }
  48. extension NSObject {
  49. static var className: String {
  50. String(describing: Self.self)
  51. }
  52. }