gpt4 book ai didi

objective-c - "id (*IMP)(id, SEL, ...) "中的第二个参数是做什么用的?

转载 作者:行者123 更新时间:2023-12-02 06:19:38 34 4
gpt4 key购买 nike

我的问题如标题所述。显然,第一个参数用于此指针,有点像 c++。第二个参数呢?谢谢你。

最佳答案

objc_msgSend() 的签名是:

id objc_msgSend(id self, SEL op, ...);

每个方法调用都被编译为对该函数的调用。即,如果您调用:

[anArray objectAtIndex:42];

这将被编译为:

objc_msgSend(anArray, @selector(objectAtIndex:), 42);

现在,对于你的问题,为什么方法被编译成一个以 SEL 作为第二个参数的函数。或者,更具体地说,为什么是这种方法:

- (id)objectAtIndex:(NSUInteger)index;

完全等价于这个 C 函数:

id object_at_index(id object, SEL _cmd, NSUInteger index);

答案是速度 speed speed

速度

具体来说,通过这样做,objc_msgSend() 永远不必重写堆栈帧*,它还可以使用尾调用优化直接跳转到方法调用。这就是为什么您永远不会在调试器的回溯中看到 objc_msgSend() 的原因(除了当您在 Messenger 中实际崩溃/中断时)。

objc_msgSend() 使用 object_cmd 来查找方法的实现,然后,从字面上看,跳转到那个实现。

非常快。堆栈框架未受影响。

而且,正如其他人所说,出于各种原因,在方法实现中使用 _cmd 可能很方便。同样,这也意味着 Messenger 可以使用巧妙的技巧,例如通过 NSInvocation 等提供代理支持。

*重写栈帧可能会异常复杂和昂贵。一些参数有时可能在寄存器中,等等......所有依赖于架构的 ABI 肮脏。编写诸如 imp_implementationWithBlock() 之类的东西的最大挑战之一是弄清楚如何不接触堆栈,因为这样做太慢而且太臃肿以至于无法实现可行。

关于objective-c - "id (*IMP)(id, SEL, ...) "中的第二个参数是做什么用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14305191/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com