【发布时间】:2009-12-11 19:54:49
【问题描述】:
更新我通过实施Mark 的建议修复了代码,以消除覆盖方法的重复并跟踪属性或方法的创建者。还没有处理属性类型(当我这样做时可能会以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)
【问题讨论】:
-
这个的用例是什么?我可以看到它在调试器控制台中很有用,除了在那里,您可以执行代码完成以获取相同的信息。
-
我对 Objective-C 还是比较陌生,所以我正在迭代。很多。不是为了改进或重构代码,而是为了让它工作。属性和方法签名与我最初的期望和设计相比发生了很大变化。能够只转储一个类的当前签名而不必点击三个或四个源文件来拼凑一张清晰的图片会很好。由于从 NSObject 继承的所有非特定方法和属性,代码完成对我不起作用。
-
看来这个问题的答案就在问题中!不错的作品。这帮了我很多忙。
标签: objective-c oop reflection