6

I have subclass of NSObject having 70 properties, i need to observe change in all of them without adding each property one-by-one using following :

[self addObserver: self
       forKeyPath: @"propertyname"
          options: NSKeyValueObservingOptionNew
          context: NULL];

. Please let me know the easiest way to do that. Right now,i need solution for 10.5 and later.

AmitSri
  • 1,209
  • 1
  • 20
  • 48

1 Answers1

10

You could use the objective-C runtime function class_copyPropertyList() to get all the properties of that class, then loop through the list and use property_getName() to get something that should work with key value observing.

Or you could implement keyPathsForValuesAffectingValueForKey: on the class in question. Make a new key on the class, that we're only going to use for change detection. Then implement the above method, and if the passed in string is equal to your new key, return a set containing the names of all seventy properties. Then you can just do KVO on your new key, and you'll get notified when anything changes. Doing it this way, you won't know which property changed, just that one of them did.

It might help to tell us why you need to do this, as there might be a better design pattern to use.

Amy Worrall
  • 16,250
  • 3
  • 42
  • 65
  • Thanks for your valuable answer. My class properties are directly bind with several UI controls in XIB. I am in need to allow users to detect change in current UI controls and notify user to save changes if they close the Main XIB without saving the current values. I'll try to implement as you mention and will let me know if that works for me. – AmitSri Jun 15 '11 at 09:00
  • Given that use case, I really want there to be a better way of doing this. I've been reading around NSObjectController in case it does what you want, but I can't find much info for situations where you're not using Core Data. I haven't tried this, but it seems like an idea: make an NSObjectController subclass, instantiate in IB, and set its content object to be your NSObject. Bind all your UI to the NSObjectController, with the same keys. Then, in code, override `objectDidEndEditing:` on your controller subclass, and have that call a method on whatever class should do the saving. – Amy Worrall Jun 15 '11 at 09:41
  • Thanks for your suggestion, I'll see if i can change my implementation in future as you suggested. Currently, i have implemented keyPathsForValuesAffectingValueForKey as you suggested and it seems to work for me now. – AmitSri Jun 16 '11 at 04:43