问题描述
是否有内置的方法、函数、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 反射 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.
推荐答案
更新: 任何想做此类事情的人都可能想查看 Mike Ash 用于 Objective-C 运行时的 ObjC 包装器.
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
);
}
这篇关于Objective-C 内省/反思的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!