在 Objective C 中,如何通过反射找出方法的返回类型?
@interface Foo : NSObject {
}
- (Bar)bar;
在运行时,给定[Foo class],我们如何找出Foo所有方法的返回类型?
我已经研究 Objective-C 运行时 API 一段时间了;据我所知,没有办法获取方法或属性的返回类型(即类)。这似乎是任何反射 API 中的一个严重遗漏。
@interface Foo : NSObject {
}
- (Bar)bar;
At runtime, given [Foo class], how do we find out the return type of all methods Foo has?
I have been studying the Objective-C runtime API for a while now; as far as I could tell, there is no way to get the return type (i.e. Class) of a method or a property. This seems to be a serious omission in any reflection API.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您可以使用 Objective-C 运行时函数:
Objective-C 运行时参考
首先,使用
class_getClassMethod
获取方法对象,然后使用
method_getReturnType
:You can use the Objective-C runtime functions:
Objective-C Runtime Reference
First of all, get the method object, using
class_getClassMethod
Then, asks for the return type using
method_getReturnType
:您可以辨别基本信息,例如它是什么 C 类型,但无法区分返回类型上的各种实例类型(或类)。
Objective-C 从未被设计或意图具有这种程度的反射。主要是因为这样做会大大增加可执行文件(所有元数据)的大小,并且支持所有 C 类型(想想 C++ 类型)的完整参数/返回类型元数据自省将非常复杂。
已经存在这样的情况:将 C++ 对象传递给 Objective-C 方法时,与方法参数化相关的元数据的数量级比生成的代码大(字面意思是单个方法调用的元数据的 MB 数) 。
参数/返回类型元数据形式的相对简单类型的示例:
以及来自 WebKit 的一个特别令人震惊的示例:
You can tell basic information like what C type it is, but you can't differentiate between various instance types (or classes) on the return type.
Objective-C was never designed nor intended to have that level of a reflection. Mostly because doing so would massively increase the size of the executables (all the metadata) and supporting full argument/return-type metadata introspection for all C types -- think C++ types -- would be incredibly complex.
Already, there have been cases where the metadata related to the parameterization of methods has measured in the orders of magnitude larger than the generated code when passing C++ objects to Objective-C methods (literally -- MBs for the metadata for a single method call).
An example of a relatively simple type in argument/return-type metadata form:
And a particularly egregious example from the WebKit: