KeyValueObserver.m 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. //
  2. // KeyValueObserver.m
  3. // Lab Color Space Explorer
  4. //
  5. // Created by Daniel Eggert on 01/12/2013.
  6. // Copyright (c) 2013 objc.io. All rights reserved.
  7. //
  8. #import "KeyValueObserver.h"
  9. //
  10. // Created by chris on 7/24/13.
  11. //
  12. #import "KeyValueObserver.h"
  13. @interface KeyValueObserver ()
  14. @property (nonatomic, weak) id observedObject;
  15. @property (nonatomic, copy) NSString* keyPath;
  16. @property (nonatomic, assign) BOOL shouldObserver;
  17. @end
  18. @implementation KeyValueObserver
  19. - (id)initWithObject:(id)object keyPath:(NSString*)keyPath target:(id)target selector:(SEL)selector options:(NSKeyValueObservingOptions)options;
  20. {
  21. if (object == nil) {
  22. return nil;
  23. }
  24. NSParameterAssert(target != nil);
  25. NSParameterAssert([target respondsToSelector:selector]);
  26. self = [super init];
  27. if (self) {
  28. _shouldObserver = YES;
  29. self.target = target;
  30. self.selector = selector;
  31. self.observedObject = object;
  32. self.keyPath = keyPath;
  33. [object addObserver:self forKeyPath:keyPath options:options context:(__bridge void *)(self)];
  34. }
  35. return self;
  36. }
  37. + (NSObject *)observeObject:(id)object keyPath:(NSString*)keyPath target:(id)target selector:(SEL)selector __attribute__((warn_unused_result));
  38. {
  39. return [self observeObject:object keyPath:keyPath target:target selector:selector options:0];
  40. }
  41. + (NSObject *)observeObject:(id)object keyPath:(NSString*)keyPath target:(id)target selector:(SEL)selector options:(NSKeyValueObservingOptions)options __attribute__((warn_unused_result));
  42. {
  43. return [[self alloc] initWithObject:object keyPath:keyPath target:target selector:selector options:options];
  44. }
  45. - (void)observeValueForKeyPath:(NSString*)keyPath ofObject:(id)object change:(NSDictionary*)change context:(void*)context
  46. {
  47. if (context == (__bridge void *)(self)) {
  48. [self didChange:change];
  49. }
  50. }
  51. - (void)didChange:(NSDictionary *)change {
  52. if (!self.shouldObserver) {
  53. return;
  54. }
  55. id strongTarget = self.target;
  56. if ([strongTarget respondsToSelector:self.selector]) {
  57. #pragma clang diagnostic push
  58. #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
  59. [strongTarget performSelector:self.selector withObject:change];
  60. #pragma clang diagnostic pop
  61. }
  62. }
  63. - (void)dealloc {
  64. [self.observedObject removeObserver:self forKeyPath:self.keyPath];
  65. }
  66. - (void)unObserver {
  67. self.shouldObserver = NO;
  68. }
  69. @end