如何检查Objective-C中的类?

时间:2009-12-11 19:54:50

标签: objective-c oop reflection

更新我修复了代码以消除重写方法的重复,并通过实施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)

2 个答案:

答案 0 :(得分:2)

runtime.h提供的c库的一个很好的帮助器/包装器是https://github.com/mikeash/MAObjCRuntime

我刚刚开始使用它,但它看起来很有希望。

就用例而言,我的目的只是提供一个检查员来构建一个可以附加到对象图的自我布线UI。这有很多潜在的重复代码减少。

答案 1 :(得分:1)

看起来像你需要的是一个NSMutableDictionary,键入选择器名称。将每个选择器名称作为键添加到字典中,并将类名作为值。您可以在添加选择器之前搜索字典,以消除重复项。