gpt4 book ai didi

objective-c - 为什么这个内联汇编调用libobjc中的release、retain和autorelease?

转载 作者:太空狗 更新时间:2023-10-30 03:33:21 26 4
gpt4 key购买 nike

下面的代码片段摘自 Apple 的 ObjC 运行时 (libobjc) 源代码。我想知道这到底是什么意思。 (不是很谷歌,抱歉)

// HACK -- the use of these functions must be after the @implementation
id bypass_msgSend_retain(NSObject *obj) asm("-[NSObject retain]");
void bypass_msgSend_release(NSObject *obj) asm("-[NSObject release]");
id bypass_msgSend_autorelease(NSObject *obj) asm("-[NSObject autorelease]");

更新:

这是对 bypass_msgSend_release() 的调用生成的内容:

movl    -4(%ebp), %eax
movl %eax, (%esp)
calll "-[NSObject release]"

最佳答案

下面是文件后面的 retain 的实际实现:

__attribute__((aligned(16)))
id
objc_retain(id obj)
{
if (!obj || OBJC_IS_TAGGED_PTR(obj)) {
goto out_slow;
}
#if __OBJC2__
if (((class_t *)obj->isa)->hasCustomRR()) {
return [obj retain];
}
return bypass_msgSend_retain(obj);
#else
return [obj retain];
#endif
out_slow:
// clang really wants to reorder the "mov %rdi, %rax" early
// force better code gen with a data barrier
asm volatile("");
return obj;
}

因此,如果它是标记指针,则什么都不做。很公平,这意味着它实际上与堆上的任何内容都不相关,也没有保留计数。

否则在过去,他们只会向对象发送消息 retain。现在,如果注意到对象包含自定义 retain(毫无疑问,旧运行时不会记录某些内容,因此会进行版本检查),他们会将 retain 消息发送给对象,否则他们会使用旁路法。

旁路似乎直接调用了 [NSObject retain] 的已知地址。

所以我猜?这是一个速度优化。如果您知道没有自定义保留,并且实际上直接跳转到 IMP,那么您就可以节省动态分派(dispatch)的成本。鉴于编译器现在在 ARC 下自动抛出 C 调用(特别是不是 Objective-C 调用),这意味着您永远不会进入更昂贵的东西。

关于objective-c - 为什么这个内联汇编调用libobjc中的release、retain和autorelease?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23526921/

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