Put simply, is there a way to receive a general notification when any property in an Objective-C class is changed? I know I can use KVO to monitor particular property changes, but I have the need to call a particular method whenever any setProperty:
message is sent to my class. I want to be able to receive a generic notification without any concern about which property in particular was modified.
If it helps to clarify why I want to do this, I am making use of some fast table scrolling code found here: http://blog.atebits.com/2008/12/fast-scrolling-in-tweetie-with-uitableview/
Part of the process of accomplishing this is that whenever a property in a table view cell is modified, [ self setNeedsDisplay ]
needs to be called. I'd rather not have to override the setter methods for every property in my class just to make this call.
As Chuck notes, you can create a dependent key, or of course you can directly observe all the properties (which is less work than overloading the setters).
Using the Objective-C runtime, if you exclusively use properties, you can automate this process using class_copyPropertyList()
. But I'd probably only do this if this problem comes up a bit for you. If you only have one instance of this problem, it's probably easier and safer and more maintainable just to directly observe the list of properties unless you feel like working in the ObjC runtime.
Here's an example built off of Chuck and Rob's suggestions:
DrakeObject.h
@interface DrakeObject : NSObject
@property (nonatomic, strong) NSNumber *age;
@property (nonatomic, strong) NSNumber *money;
@property (nonatomic, strong) NSString *startPosition;
@property (nonatomic, strong) NSString *currentPosition;
@property (nonatomic, strong, readonly) id propertiesChanged;
@end
DrakeObject.m
@implementation DrakeObject
- (instancetype)init {
self = [super init];
if (self) {
self.age = @25;
self.money = @25000000;
self.startPosition = @"bottom";
self.currentPosition = @"here";
}
return self;
}
- (id)propertiesChanged {
return nil;
}
+(NSSet *)keyPathsForValuesAffectingPropertiesChanged {
return [NSSet setWithObjects:@"age", @"money", @"startPosition", @"currentPosition", nil];
}
observing propertiesChanged will let us know anytime a property has changed.
[self.drakeObject addObserver:self
forKeyPath:@"propertiesChanged"
options:NSKeyValueObservingOptionNew
context:nil];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With