是否有内置的方法、函数、API、普遍接受的方式等来转储 Objective-C 中实例化对象的内容,特别是在 Apple 的 Cocoa/Cocoa-Touch 环境中?
我希望能够做类似的事情
MyType *the_thing = [[MyType alloc] init];
NSString *the_dump = [the_thing dump]; //pseudo code
NSLog("Dumped Contents: %@", the_dump);
并显示对象的实例变量名称和值,以及在运行时可调用的任何方法。最好是易于阅读的格式。
对于熟悉 PHP 的开发人员,我基本上是在寻找反射函数(var_dump()、get_class_methods())和 OO Reflection API 的等价物。
最佳答案
更新:任何想要做这类事情的人都可能想查看 Mike Ash's ObjC wrapper for the Objective-C runtime .
这或多或少是你的做法:
#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);
}
从那里,很容易得到实例属性的实际值,但是你必须检查它们是原始类型还是对象,所以我懒得放了。你也可以选择扫描继承链来获取对象上定义的所有属性。然后是在类别上定义的方法,等等……但几乎所有东西都是现成的。
以下是 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 内省(introspection)/反射(reflection),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2299841/
我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U
我正在为ruby开发一个C扩展,但我需要包含来自IOBluetooth框架的header,特别是:#import#import一切都编译正常,但在运行时,扩展错误:path/to/file.rb:1:in`require_relative':dlopen(/path/to/extension.bundle,9):Symbolnotfound:_OBJC_CLASS_$_IOBluetoothDeviceInquiry(LoadError)我相当确定这与未包含在链接过程中的框架有关,但我不确定原因。任何帮助将不胜感激extconf.rb:#Loadsmkmfwhichisusedto
在我的Rails应用程序中,我收到来自brakeman的以下安全警告。使用模型属性调用的不安全反射方法常量化。这是我的代码正在执行的操作。chart_type=Chart.where(id:chart_id,).pluck(:type).firstbeginChartPresenter.new(chart_type.camelize.constantize.find(chart_id))rescueraise"Unabletofindthechartpresenter"end根据我的研究,我还没有找到任何具体的解决方案。我听说你可以创建一个白名单,但我不确定brakeman在寻找什么。
我最近一直在学习ruby,并且基本上爱上了||=特性,因为它可以使在ObjectiveC中编写惰性getter变得更加容易。目前我写的getter如下:-(NSArray*)myArray{if(!_myArray){_myArray=[NSArrayarray];}return_myArray}除非我遗漏了||=的某些内容,否则我将能够使用Ruby编写以前的代码:-(NSArray*)myArray{return_myArray||=[NSArrayarray];}那显然更干净了。Objective-C语言/运行时中是否有任何东西可以让您做到这一点?此外,以下是getter的单行
我很好奇这是如何工作的。例如,如果我创建一个基于工厂模式的类,您可以在其中“注册”类供以后使用,然后执行类似FactoryClass.register('YourClassName',[param,param,...]);FactoryClass.create('your_class_name').call_method_from_this_object其中'class_name'是映射到值的散列中的键:ClassName有没有类似phpreflection的东西,我可以在哪里创建基于字符串名称的类的实例并传入参数?(在php中,参数将是它们的数组,php然后知道如何处理)所以如果我们
我没有Mac或iPhone。然而,采用C并使其更加动态地朝着smalltalk、python或ruby的想法发展的概念对我来说确实很有吸引力。我很乐意从Objective-C开始。Objective-C只是C的语法超集还是真的像C。比如,它可以用gcc等编译吗?我的大部分编程都是用Ruby完成的。ObjectiveC似乎比C宽容得多。您可以在C中为Ruby编写native扩展。您可以在ObjectiveC中为Ruby编写native扩展吗?除了拥有Mac/iPhone和XCode之外,我如何开始使用ObjectiveC? 最佳答案
我刚刚发现MacRuby/HotCocoa,非常喜欢他们正在做的事情的声音。我基本上不考虑自己制作CocoaGUI应用程序的前景,因为我厌恶花时间和精力学习另一种基于C的语言Objective-C。我并不是说它不好,只是不适合我。现在或在可能的future,是否可以完全忽略Objective-C而仅使用MacRuby/HotCocoa来制作具有实质性和一流性质的CocoaGUI应用程序?(编辑:桌面Mac,而非iPhone) 最佳答案 "ItisthegoalofMacRubytoenablethecreationoffull-fl
我想弄清楚如何将用Ruby(Sass)编写的包捆绑到Cocoa应用程序(Objective-C,而不是RubyCocoa)中供我执行(通过NSTask很好,除非有是桥接ObjCCocoa的简单方法,我不知道)。Sass包是您必须安装的东西,使用“geminstall”或“rakeinstall”——这样做会在我的~/.gem目录中放置吨文件。因为我希望任何安装了我的基于Cocoa的应用程序的人都能够从我的应用程序中执行这个工具,我不想让用户经历安装任何额外的过程,所以我希望能够将我需要的所有内容嵌入到我的应用程序包的Resources目录中。但是,我对Ruby的内部结构和结构不是那么熟
呈现成语我找到了一个interestingbutunexplainedalternative到一个公认的答案。该代码在REPL中显然有效。例如:moduleFooclassBardefbazendendendFoo.constants.map(&Foo.method(:const_get)).grep(Class)=>[Foo::Bar]但是,我并不完全理解这里使用的成语。特别是,我不明白&Foo的用法,它似乎是某种闭包,或者#grep的这种特定调用如何对结果进行操作。解析成语到目前为止,我已经能够解析其中的点点滴滴,但我并没有真正看到它们是如何组合在一起的。以下是我认为对示例代码的理
我是从PHP开始接触ruby的。我怎么能用ruby做下一件事?$className='ArrayObject';$arrayObject=new$className(); 最佳答案 你可以这样做:arrayObject=Object::const_get('Array').new 关于ruby-Ruby中的反射。通过给定的类名实例化一个对象,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/qu