我想覆盖setter和getter并找到objc_property_t
的类,而不是为每个属性单独执行它。
我得到了所有的属性:
unsigned int numberOfProperties;
objc_property_t *propertyArray = class_copyPropertyList([self class], &numberOfProperties);
for (NSUInteger i = 0; i < numberOfProperties; i++) {
objc_property_t property = propertyArray[i];
NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)];
property.getter = SEL; //?
}
这是我想要覆盖getter和setter的示例 - 如果有更好的方法,请告诉我。 NSInvocation可能吗?
- (UIImage *)backgroundImage
{
return [self overrideGetterWithSelector:NSStringFromSelector(_cmd)];
}
- (void)setBackgroundImage:(UIImage *)backgroundImage
{
[self overrideSetterForObject:backgroundImage forSelector:NSStringFromSelector(_cmd)];
}
或者有没有办法拦截发送给班级的所有邮件?
我的目标是制作一种在启动之间存储类属性的通用方法。您可能想问我为什么不使用NSUserDefaults
或NSKeyedArchiver
。好吧,我正在使用NSKeyedArchiver
- 我不想手动覆盖每一个setter和getter。
答案 0 :(得分:6)
您可以使用objc运行时中的class_replaceMethod
来替换getter的实现。
示例:
- (void)replaceGetters {
unsigned int numberOfProperties;
objc_property_t *propertyArray = class_copyPropertyList([self class], &numberOfProperties);
for (NSUInteger i = 0; i < numberOfProperties; i++) {
objc_property_t property = propertyArray[i];
const char *attrs = property_getAttributes(property);
NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)];
// property.getter = SEL; //?
// becomes
class_replaceMethod([self class], NSSelectorFromString(name), (IMP)myNewGetter, attrs);
}
}
id myNewGetter(id self, SEL _cmd) {
// do whatever you want with the variables....
// you can work out the name of the variable using - NSStringFromSelector(_cmd)
// or by looking at the attributes of the property with property_getAttributes(property);
// There's a V_varName in the property attributes
// and get it's value using - class_getInstanceVariable ()
// Ivar ivar = class_getInstanceVariable([SomeClass class], "_myVarName");
// return object_getIvar(self, ivar);
}
答案 1 :(得分:2)
您可以在此设置KVO并在更改时保存数据。
static const void *KVOContext = &KVOContext;
unsigned int numberOfProperties;
objc_property_t *propertyArray = class_copyPropertyList([self class], &numberOfProperties);
for (NSUInteger i = 0; i < numberOfProperties; i++)
{
objc_property_t property = propertyArray[i];
NSString *name = [[NSString alloc] initWithUTF8String:property_getName(property)];
[self addObserver:self forKeyPath:name options:kNilOptions context:KVOContext];
}