How to resolve property getter/setter method selector using runtime reflection in Objective-C? (or reverse)
-
13-03-2021 - |
سؤال
Objective-C offers runtime reflections feature. I'm trying to find getter/setter selector name of a declared property. I know the basic rule like field
/setField:
. Anyway I think runtime reflection should offer a feature to resolve the name for complete abstraction, but I couldn't find the function.
How can I resolve the getter/setter method selector (not implementation) of a declared property with runtime reflection in Objective-C (actually Apple's Cocoa)
Or reverse query. (method selector → declared property)
المحلول
I think you can get the selector names only if the property is declared with explicit (setter = XXX and/or getter = XXX)
So to get the getter and setter selector names for some property 'furType' of the class 'Cat':
objc_property_t prop = class_getProperty([Cat class], "furType");
char *setterName = property_copyAttributeValue(prop, "S");
if (setterName == NULL) { /*Assume standard setter*/ }
char *getterName = property_copyAttributeValue(prop, "G");
if (getterName == NULL) { /*Assume standard getter */ }
I don't know of a reverse query, other than iterating through all the properties and looking for matches. Hope that helps.
نصائح أخرى
A little update from my NSObject category. Hope this'll help some one:
+(SEL)getterForPropertyWithName:(NSString*)name {
const char* propertyName = [name cStringUsingEncoding:NSASCIIStringEncoding];
objc_property_t prop = class_getProperty(self, propertyName);
const char *selectorName = property_copyAttributeValue(prop, "G");
if (selectorName == NULL) {
selectorName = [name cStringUsingEncoding:NSASCIIStringEncoding];
}
NSString* selectorString = [NSString stringWithCString:selectorName encoding:NSASCIIStringEncoding];
return NSSelectorFromString(selectorString);
}
+(SEL)setterForPropertyWithName:(NSString*)name {
const char* propertyName = [name cStringUsingEncoding:NSASCIIStringEncoding];
objc_property_t prop = class_getProperty(self, propertyName);
char *selectorName = property_copyAttributeValue(prop, "S");
NSString* selectorString;
if (selectorName == NULL) {
char firstChar = (char)toupper(propertyName[0]);
NSString* capitalLetter = [NSString stringWithFormat:@"%c", firstChar];
NSString* reminder = [NSString stringWithCString: propertyName+1
encoding: NSASCIIStringEncoding];
selectorString = [@[@"set", capitalLetter, reminder, @":"] componentsJoinedByString:@""];
} else {
selectorString = [NSString stringWithCString:selectorName encoding:NSASCIIStringEncoding];
}
return NSSelectorFromString(selectorString);
}