Update我修复了代码,以消除重写方法的重复,并通过实现来跟踪属性或方法的发起者Mark https://stackoverflow.com/questions/1890480/how-do-i-inspect-a-class-in-objective-c/1892127#1892127的建议。还没有解决财产类型(可能会从property_getAttributes()
当我做)。还去掉了残留的下划线。
基本上,我需要一种方法来提醒自己给定对象上有哪些方法和属性可用,而不需要一路跳到继承树上。
我已经编写了以下函数,但还有一些不足之处:
#import <objc/runtime.h>
NSInteger inspectClass_alphabeticSort(id string1, id string2, void *reverse)
{
if ((NSInteger *)reverse == NO)
{
return [string2 localizedCaseInsensitiveCompare:string1];
}
return [string1 localizedCaseInsensitiveCompare:string2];
}
void inspectClassStopAt(Class inspectedClass, Class stopClass)
{
Class originalClass = inspectedClass;
NSString *originalClassString = [NSString stringWithFormat:@"%@", originalClass];
NSString *inheritancePath = [NSString stringWithFormat:@"%@", originalClass];
Method *methods;
objc_property_t *properties;
unsigned int i;
unsigned int methodCount;
unsigned int propertyCount;
int reverseSort = NO;
NSArray *sorted;
NSArray *methodsAndPropertiesKeys;
NSMutableDictionary * methodsAndProperties = [NSMutableDictionary dictionaryWithCapacity:10];
NSString *inspectedClassString;
NSString *methodOrPropertyName;
while (inspectedClass != stopClass)
{
inspectedClassString = [NSString stringWithFormat:@"%@", inspectedClass];
if (inspectedClass != originalClass)
{
inheritancePath = [inheritancePath stringByAppendingFormat:@" : %@", inspectedClass];
}
methods = class_copyMethodList(inspectedClass, &methodCount);
properties = class_copyPropertyList(inspectedClass, &propertyCount);
for (i=0; i<methodCount; i++)
{
methodOrPropertyName = [NSString stringWithFormat:@"-%s", sel_getName(method_getName(methods[i]))];
if (![methodsAndProperties objectForKey:methodOrPropertyName])
{
[methodsAndProperties setObject:inspectedClassString forKey:methodOrPropertyName];
}
}
for (i=0; i<propertyCount; i++)
{
methodOrPropertyName = [NSString stringWithFormat:@" %s", property_getName(properties[i])];
if (![methodsAndProperties objectForKey:methodOrPropertyName])
{
[methodsAndProperties setObject:inspectedClassString forKey:methodOrPropertyName];
}
}
inspectedClass = [inspectedClass superclass];
}
free(methods);
free(properties);
methodsAndPropertiesKeys = [methodsAndProperties allKeys];
sorted = [methodsAndPropertiesKeys sortedArrayUsingFunction:inspectClass_alphabeticSort context:&reverseSort];
NSLog(@"%@", inheritancePath);
for (NSString *key in sorted)
{
if (![[methodsAndProperties objectForKey:key] isEqualToString:originalClassString])
{
NSLog(@"\t%@ (%@)", key, [methodsAndProperties objectForKey:key]);
}
else
{
NSLog(@"\t%@", key);
}
}
}
void inspectClass(Class inspectedClass)
{
inspectClassStopAt(inspectedClass, [NSObject class]);
}
以及一些示例输出inspectClass([TextMap class]);
:
TextMap : Surface
position (Surface)
size (Surface)
-addChild: (Surface)
-dealloc
-init (Surface)
-initWithFile:
-position (Surface)
-render
-setPosition: (Surface)
-setSize: (Surface)
-setText:
-size (Surface)
-update (Surface)