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

问题描述

在Objective C中,特别是在Apple的Cocoa / Cocoa-Touch环境中,有一个内置的方法,函数,API,通常接受的方式等来转储实例化对象的内容吗?

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?

我想能够做一些像

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

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

08-26 17:57