If all i have is a list of keys, is there an elegant way to test an object for read-only vs. read/write properties? I realize I could string-bang the key:
NSString *setterString = [@"set" stringByAppendingString:[someKeyString capitalizedString]];
BOOL isReadWrite = [myObject respondsToSelector:NSSelectorFromString(setterString)];
Or better yet try to set a value for the key and check for an NSUndefinedKeyException
- but using exceptions for non-exceptional behavior seems like poor form.
To be clear, i'd like to programmatically audit an object's properties and tell the difference between, for instance,
@property (readonly) NSString *someReadOnlyKey
@property NSString *someReadWriteProperty
edit: To be more clear, it shouldn't matter if the keys are implemented as @property
s or manual getter/setter. Only concerned about public interface. And thanks for asking what I'm trying to accomplish - that's probably more important to get right in the first place.
I'm trying to sketch out some code that generates graphic representations of an object's keys. All the keys are known beforehand - but I won't always know which keys will be sett-able (it's up to the particular subclass to implement)
You have two valid approaches:
respondsToSelector:
methodI'll try to summarize the implication of both approaches, along with their drawbacks. You can then choose the approach more suitable to your needs.
//MyClass.h
@property (readonly) NSString *someReadOnlyKey;
Ok, everything works as expected.
//MyClass.h
@property (readonly) NSString *someReadOnlyKey;
///////////////////////////////////////////////////////////////////////////
//MyClass.m
@property (readwrite) NSString *someReadOnlyKey;
If the property definition has been overridden, you'll get the actual property attribute being used. It doesn't matter whether you query about it from where the setter is visible, i.e. inside the class definition, or from outside. You will get the actual definition that has been used to synthesize the accessor methods.
//MyClass.h
@property (setter=myCoolSetter) NSString *someReadOnlyKey;
With a custom setter name, the respondsToSelector
trick won't work anymore, whereas the runtime is still providing the correct information.
//MyClass.h
@property (readonly) NSString *someReadOnlyKey;
///////////////////////////////////////////////////////////////////////////
//MyClass.m
- (void)setSomeReadOnlyKey:(NSString *)someReadOnlyKey {
_someReadOnlyKey = someReadOnlyKey;
}
This time the runtime is failing, since the setter is there, but the property definition "doesn't know" about it.
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