RACKVOProxy.m 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. //
  2. // RACKVOProxy.m
  3. // ReactiveObjC
  4. //
  5. // Created by Richard Speyer on 4/10/14.
  6. // Copyright (c) 2014 GitHub, Inc. All rights reserved.
  7. //
  8. #import "RACKVOProxy.h"
  9. @interface RACKVOProxy()
  10. @property (strong, nonatomic, readonly) NSMapTable *trampolines;
  11. @property (strong, nonatomic, readonly) dispatch_queue_t queue;
  12. @end
  13. @implementation RACKVOProxy
  14. + (instancetype)sharedProxy {
  15. static RACKVOProxy *proxy;
  16. static dispatch_once_t onceToken;
  17. dispatch_once(&onceToken, ^{
  18. proxy = [[self alloc] init];
  19. });
  20. return proxy;
  21. }
  22. - (instancetype)init {
  23. self = [super init];
  24. _queue = dispatch_queue_create("org.reactivecocoa.ReactiveObjC.RACKVOProxy", DISPATCH_QUEUE_SERIAL);
  25. _trampolines = [NSMapTable strongToWeakObjectsMapTable];
  26. return self;
  27. }
  28. - (void)addObserver:(__weak NSObject *)observer forContext:(void *)context {
  29. NSValue *valueContext = [NSValue valueWithPointer:context];
  30. dispatch_sync(self.queue, ^{
  31. [self.trampolines setObject:observer forKey:valueContext];
  32. });
  33. }
  34. - (void)removeObserver:(NSObject *)observer forContext:(void *)context {
  35. NSValue *valueContext = [NSValue valueWithPointer:context];
  36. dispatch_sync(self.queue, ^{
  37. [self.trampolines removeObjectForKey:valueContext];
  38. });
  39. }
  40. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
  41. NSValue *valueContext = [NSValue valueWithPointer:context];
  42. __block NSObject *trueObserver;
  43. dispatch_sync(self.queue, ^{
  44. trueObserver = [self.trampolines objectForKey:valueContext];
  45. });
  46. if (trueObserver != nil) {
  47. [trueObserver observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  48. }
  49. }
  50. @end