物镜自省/反思 [英] Objective-C Introspection/Reflection

查看:76
本文介绍了物镜自省/反思的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有内置的方法,函数,API,常用方法等在Objective-C中转储实例化对象的内容,特别是在Apple的Cocoa/Cocoa-Touch环境中?

Is there a built in method, function, API, commonly accepted way, etc. to dump the contents of an instantiated object in Objective-C, specifically in Apple's Cocoa/Cocoa-Touch environment?

我希望能够做类似的事情

I want to be able to do something like

MyType *the_thing = [[MyType alloc] init];
NSString *the_dump = [the_thing dump]; //pseudo code
NSLog("Dumped Contents: %@", the_dump);

,并显示对象的实例变量名称和值,以及在运行时可调用的任何方法.理想情况下是易于阅读的格式.

and have the object's instance variable names and values displayed, along with any methods available to call at run time. Ideally in an easy to read format.

对于熟悉PHP的开发人员,我基本上是在寻找反射函数(var_dump()get_class_methods())和OO Reflection API的等效项.

For developers familiar with PHP, I'm basically looking for the equivalent of the reflection functions (var_dump(), get_class_methods()) and the OO Reflection API.

推荐答案

更新:任何想要做这种事情的人都可能想看看

UPDATE: Anyone looking to do this kind of stuff might want to check out Mike Ash's ObjC wrapper for the Objective-C runtime.

这或多或少是您要做的事情:

This is more or less how you'd go about it:

#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);
}

从那里很容易获得实例属性的实际值,但是您必须检查它们是原始类型还是对象,因此我懒得将其放入.您还可以选择扫描继承链以获取所有在对象上定义的属性.然后是在类别上定义的方法,还有更多...但是几乎所有内容都随时可用.

From there, it's easy to get the actual values of an instance's properties, but you have to check to see if they are primitive types or objects, so I was too lazy to put it in. You could also choose to scan the inheritance chain to get all the properties defined on an object. Then there are methods defined on categories, and more... But almost everything is readily available.

以下是上述代码为UILabel转储的内容的摘录:

Here's an excerpt of what the above code dumps for 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
    );
}

这篇关于物镜自省/反思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆