Jas*_*ues 1 objective-c objective-c-runtime
在objective-C运行时,为什么method_getNumberOfArguments返回的结果比选择器所暗示的多两个?
例如,为什么@selector(initWithPrice:color :)返回4?
好的.只是为了直接设置记录,是的,任何objective-c方法的前两个参数都是,self并且_cmd始终按此顺序.
然而,更有趣的主题是这种情况的原因.要做到这一点,我们首先要看看objc的历史.不用多说,让我们开始吧.
早在1983年,Objective Co的"上帝"Brad Cox就想在 C 之上创建一个面向对象的基于运行时的语言,以实现跨平台的良好性能和灵活性.因此,第一个Objective-C'编译器'只是将Objective-C源的简单预处理器转换为它们的C-runtime等价物,然后使用特定于平台的C编译器工具进行编译.
但是,C不是为对象设计的,而这是Objective-C必须克服的最基本的东西.虽然C是一种强大而灵活的语言,但运行时支持是其中一个重要的垮台.
在Objective-C的早期设计阶段,决定对象将是一个纯粹的基于堆的指针设计,这样它们就可以在任何函数之间传递而没有奇怪的复制语义等等(这在Obj-C++中有所改变)和ARC,但这个帖子的范围太宽了),并且每个方法都应该是自我意识的(正如bbum指出的那样,这是使用与原始函数调用相同的堆栈帧的优化),所以理论上,您可以将多个方法名称映射到同一个选择器,如下所示:
// 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;
}
Run Code Online (Sandbox Code Playgroud)
然后,该函数可以理论上映射到两个选择器,name并且age基于调用哪个来执行条件代码.在一般的Objective-C代码中,这并不算太大,因为现在使用ARC将函数映射到选择器是非常困难的,因为演员等等,但语言从那时起已经发展了很多.
希望这有助于您了解Objective-C方法的两个"不可见"参数背后的原因,第一个是被调用的对象,第二个是在该对象上调用的方法.
| 归档时间: |
|
| 查看次数: |
350 次 |
| 最近记录: |