- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在 Objective-C 运行时,为什么 method_getNumberOfArguments 返回的结果比选择器暗示的多两个?
例如,为什么@selector(initWithPrice:color:)返回4?
最佳答案
好的。澄清一下,是的,任何 Objective-C 方法的前两个参数都是 self
和 _cmd
,始终按此顺序。
但是,更有趣的主题是这种情况的原因。为此,我们必须首先了解 objc 的历史。事不宜迟,让我们开始吧。
早在 1983 年,Brad Cox,objective-c 的“上帝”,想要在 C 之上创建一种面向对象的基于运行时的语言,以实现跨平台的良好性能和灵 active .因此,最早的 Objective-C“编译器”只是将 Objective-C 源代码转换为 C 运行时等价物的简单预处理器,然后使用平台特定的 C 编译器工具进行编译。
然而,C 并不是为对象而设计的,而这是 Objective-C 必须克服的最基本的事情。虽然 C 是一种健壮且灵活的语言,但运行时支持是它的一个关键缺点。
在 Objective-C 的早期设计阶段,决定对象将是一个纯粹基于堆的指针设计,这样它们就可以在任何函数之间传递而没有奇怪的复制语义等(这在Obj-C++ 和 ARC,但这对于这篇文章来说范围太广了),而且每个方法都应该是 self 意识的(实际上,正如 bbum 指出的那样,这是对使用相同堆栈的优化frame 作为原始函数调用),这样在理论上,您可以将多个方法名称映射到同一个选择器,如下所示:
// this is a completely valid objc 1.0 method declaration
void *nameOrAge(id self, SEL _cmd) {
if (_cmd == @selector(name)) {
return "Richard";
}
if (_cmd == @selector(age)) {
return (void *) (intptr_t) 16;
}
return NULL;
}
这个函数理论上可以映射到两个选择器,name
和 age
,并根据调用的条件代码执行条件代码。在一般的 Objective-C 代码中,这不是什么大问题,因为由于转换等原因,ARC 现在很难将函数映射到选择器,但语言从那时起已经有了很大的发展。
希望这可以帮助您理解 Objective-C 方法的两个“不可见”参数背后的原因,第一个是被调用的对象,第二个是在该对象上调用的方法。
关于objective-c - 为什么 method_getNumberOfArguments 返回的结果比选择器暗示的结果多两个?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14011119/
在 Objective-C 运行时,为什么 method_getNumberOfArguments 返回的结果比选择器暗示的多两个? 例如,为什么@selector(initWithPrice:col
我是一名优秀的程序员,十分优秀!