addObserver:forKeyPath:options:context:は一つ一つプロパティを指定しなければならず、
面倒です。そこで
@interface NSObject(ObserverALL)
- (void)addObserverAllProperties:(NSObject *)observer options:(NSKeyValueObservingOptions)options context:(void *)context;
- (void)removeObserverAllProperties:(NSObject *)observer context:(void *)context;
@end
@implementation NSObject(ObserverALL)
- (void)addObserverAllProperties:(NSObject *)observer options:(NSKeyValueObservingOptions)options context:(void *)context
{
unsigned propertyCount;
objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
for(int i = 0 ; i < propertyCount ; ++i)
{
objc_property_t property = properties[i];
const char *propName = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
[self addObserver:observer forKeyPath:propertyName options:options context:context];
// NSLog(@"add observer -> %@", propertyName);
}
free(properties);
}
- (void)removeObserverAllProperties:(NSObject *)observer context:(void *)context
{
unsigned propertyCount;
objc_property_t *properties = class_copyPropertyList([self class], &propertyCount);
for(int i = 0 ; i < propertyCount ; ++i)
{
objc_property_t property = properties[i];
const char *propName = property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:propName];
[self removeObserver:observer forKeyPath:propertyName context:context];
}
free(properties);
}
@end
とカテゴリを用意してあげます。
class_copyPropertyListを使って全プロパティを列挙して、それをaddObserverするだけの簡単なカテゴリです。
これを使えば楽に全監視できますね。
必要に応じて少々カスタマイズすれば色々な用途に使えそうです。
ヘッダーを書き忘れてました。
#import <objc/runtime.h>
が必要です