UPDATE: Chiunque cerchi di fare questo genere di cose potrebbe voler controllare Mike Ash's ObjC wrapper for the Objective-C runtime.
Questo è più o meno come ci si va su di esso:
#import <objc/runtime.h>
. . .
-(void)dumpInfo
{
Class clazz = [self class];
u_int count;
Ivar* ivars = class_copyIvarList(clazz, &count);
NSMutableArray* ivarArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count ; i++)
{
const char* ivarName = ivar_getName(ivars[i]);
[ivarArray addObject:[NSString stringWithCString:ivarName encoding:NSUTF8StringEncoding]];
}
free(ivars);
objc_property_t* properties = class_copyPropertyList(clazz, &count);
NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count ; i++)
{
const char* propertyName = property_getName(properties[i]);
[propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
}
free(properties);
Method* methods = class_copyMethodList(clazz, &count);
NSMutableArray* methodArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i < count ; i++)
{
SEL selector = method_getName(methods[i]);
const char* methodName = sel_getName(selector);
[methodArray addObject:[NSString stringWithCString:methodName encoding:NSUTF8StringEncoding]];
}
free(methods);
NSDictionary* classDump = [NSDictionary dictionaryWithObjectsAndKeys:
ivarArray, @"ivars",
propertyArray, @"properties",
methodArray, @"methods",
nil];
NSLog(@"%@", classDump);
}
Da lì, è facile ottenere i valori reali di proprietà di un esempio, ma è necessario controllare per vedere se sono primitivi tipi o oggetti, quindi ero troppo pigro per inserirli. Potresti anche scegliere di eseguire la scansione della catena di ereditarietà per ottenere tutte le proprietà definite su un oggetto. Poi ci sono metodi definiti su categorie e altro ... Ma quasi tutto è facilmente disponibile.
Ecco un estratto di ciò che il codice di cui sopra discariche per UILabel:
{
ivars = (
"_size",
"_text",
"_color",
"_highlightedColor",
"_shadowColor",
"_font",
"_shadowOffset",
"_minFontSize",
"_actualFontSize",
"_numberOfLines",
"_lastLineBaseline",
"_lineSpacing",
"_textLabelFlags"
);
methods = (
rawSize,
"setRawSize:",
"drawContentsInRect:",
"textRectForBounds:",
"textSizeForWidth:",
. . .
);
properties = (
text,
font,
textColor,
shadowColor,
shadowOffset,
textAlignment,
lineBreakMode,
highlightedTextColor,
highlighted,
enabled,
numberOfLines,
adjustsFontSizeToFitWidth,
minimumFontSize,
baselineAdjustment,
"_lastLineBaseline",
lineSpacing,
userInteractionEnabled
);
}
Mi chiedo la stessa domanda ci sono pochi giorni. Grazie per questa domanda. –
Sì, ottima domanda. Uno dei maggiori vantaggi di ObjC rispetto ad altri linguaggi simili è il suo sorprendente sistema di runtime dinamico che ti permette di fare cose fantastiche come questa. Sfortunatamente, le persone lo usano raramente al massimo delle sue potenzialità, quindi complimenti per aver insegnato alla comunità SO con la tua domanda. – rpj
Ho creato una libreria leggera per la gestione della riflessione [OSReflectionKit] (https://github.com/iAOS/OSReflectionKit). Usando questa libreria puoi chiamare semplicemente [the_thing fullDescription]. –