我知道,在C中,每个函数都会创建一个框架,当使用它的函数结束时,每个框架都会自动释放。相同的逻辑是否适用于Objective-C方法?他们在执行时是否在堆栈上创建了 frames ?
答案 0 :(得分:5)
是的,他们这样做。
Objective-C动态调用方法,所以:
[someObject doSomething];
相当于:
objc_msgSend(someObject, sel_registerName("doSomething"));
sel_registerName
返回一个选择器,它基本上是给定方法名称的方法标识符。
objc_msgSend
是用汇编编写的,代码可用here。它在对象的方法列表中查找选择器。方法列表包含选择器IMP
的{{1}},它是一个C函数指针,指向类似于的函数:
doSomething
void doSomething(id self, SEL _cmd);
然后tail-calls函数指针
因此,方法只是常规的C函数,但它们是在运行时动态调用的。调用objc_msgSend
时,返回地址被压入堆栈,CPU跳转到objc_msgSend
。看起来objc_msgSend
根本不会触及堆栈,因此该方法就像C函数一样设置堆栈帧。完成后,该方法会删除它的堆栈帧并完全按照C函数的方式返回。由于objc_msgSend
使堆栈保持不变,因此它直接返回到调用方法的代码,就像直接调用方法实现一样。