I use this to get the class for a property name:
- (Class)gm_classForPropertyName:(NSString *)propertyName {
objc_property_t prop = class_getProperty([self class], propertyName.UTF8String);
const char * attr = property_getAttributes(prop);
NSString *attributes = [NSString stringWithUTF8String:attr];
NSArray *components = [attributes componentsSeparatedByString:@"\""];
Class propertyClass;
for (NSString *component in components) {
Class class = NSClassFromString(component);
if (class) {
propertyClass = class;
break;
} else {
class = swiftClassMapping[component];
if (class) {
propertyClass = class;
break;
}
}
}
return propertyClass;
}
But this is the important part:
objc_property_t prop = class_getProperty([self class], propertyName.UTF8String);
const char * attr = property_getAttributes(prop);
NSString *attributes = [NSString stringWithUTF8String:attr];
When I log attributes
, it still looks like an untyped NSArray as a string. Is there some way to introspect the class type?
T@"NSArray",&,N,V_children
tl;dr
Take this class:
@interface SomeClass : NSObject <GenomeObject>
@property (strong, nonatomic) NSArray<SomeOtherClass *> *children;
@end
Given the class SomeClass
, and the property name children
is there a way for me to find that children
is an array of SomeOtherClass
type objects?
According to the WWDC talks about this feature, it is implemented using type erasure. That means that information about the generic is removed during compilation and not present at runtime.
This is the relevant video: https://developer.apple.com/videos/wwdc/2015/?id=401. The
lightweight generics
discussion starts at about 22 minutes. At 27:20 they explain that it is implemented using type erasure.