Objective c OBJC_PRINT_VTABLE_图像和OBJC_PRINT_VTABLE_设置不显示任何输出

Objective c OBJC_PRINT_VTABLE_图像和OBJC_PRINT_VTABLE_设置不显示任何输出,objective-c,objective-c-runtime,Objective C,Objective C Runtime,我尝试在Objective-C可执行文件上使用OBJC_PRINT_VTABLE_图像和OBJC_PRINT_VTABLE_设置环境变量,以便了解Objective-C对象中的VTABLE机制。不幸的是,所提到的环境变量对控制台输出没有影响,尽管运行时确认变量已设置: » OBJC_PRINT_OPTIONS=1 OBJC_PRINT_VTABLE_IMAGES=YES /Applications/TextEdit.app/Contents/MacOS/TextEdit objc[41098]:

我尝试在Objective-C可执行文件上使用OBJC_PRINT_VTABLE_图像和OBJC_PRINT_VTABLE_设置环境变量,以便了解Objective-C对象中的VTABLE机制。不幸的是,所提到的环境变量对控制台输出没有影响,尽管运行时确认变量已设置:

» OBJC_PRINT_OPTIONS=1 OBJC_PRINT_VTABLE_IMAGES=YES /Applications/TextEdit.app/Contents/MacOS/TextEdit
objc[41098]: OBJC_PRINT_OPTIONS is set
objc[41098]: OBJC_PRINT_VTABLE_IMAGES is set
我尝试在系统(TextEdit)和我自己提供的可执行文件上使用这两个变量。没有效果

Objective-C对象中的整个可变机制是模糊的。在苹果的网页上很难找到关于这种机制的信息。有其他来源的一些信息,但没有官方文件:


为什么这些变量不起作用?当前版本的Objective-C中的vtables是否已弃用

在这种情况下,答案非常简单-vtable分派不再在objective-c运行时进行优化,一开始可能是个坏主意

基于vtable的分派是在objective-c运行时加速频繁调用的最初尝试之一,但请注意,它早于当前的方法缓存解决方案。在vtable解决方案中使用固定选择器集的问题不仅意味着运行时每个类的内存都会增加,而且还意味着如果您使用的体系结构不会导致频繁调用
IsequalString:
,例如,现在,对于运行时中重写其中一个选择器的每个类,都有一个完全浪费的指针。哎呀

另外,请注意,Vtable dispatch by design无法在32位体系结构上工作,这意味着一旦iOS SDK发布,并且32位再次成为objective-c的合理目标,优化就无法工作

我可以在以下文件中找到这方面的相关文档:

其中,
int3
是SIGTRAP指令,如果未连接调试器(通常),它将导致崩溃


因此,虽然vtable分派在objective-c的历史上是一个有趣的注释,但我们应该将其作为一个实验来回顾,因为我们不太熟悉优化常用方法调用的最佳方法。

在这种情况下,答案非常简单-vtable分派不再在objective-c运行时进行优化,一开始可能是个坏主意

基于vtable的分派是在objective-c运行时加速频繁调用的最初尝试之一,但请注意,它早于当前的方法缓存解决方案。在vtable解决方案中使用固定选择器集的问题不仅意味着运行时每个类的内存都会增加,而且还意味着如果您使用的体系结构不会导致频繁调用
IsequalString:
,例如,现在,对于运行时中重写其中一个选择器的每个类,都有一个完全浪费的指针。哎呀

另外,请注意,Vtable dispatch by design无法在32位体系结构上工作,这意味着一旦iOS SDK发布,并且32位再次成为objective-c的合理目标,优化就无法工作

我可以在以下文件中找到这方面的相关文档:

其中,
int3
是SIGTRAP指令,如果未连接调试器(通常),它将导致崩溃


因此,虽然vtable dispatch在objective-c的历史上是一个有趣的注释,但当我们不太熟悉优化常用方法调用的最佳方法时,应该将其作为一个实验来回顾。

如果您不知道,objective-c运行时是开源的。这类问题通常可以通过查看实现来回答:在本例中,vtable和fixup分派似乎是同义词,而fixup分派在OSX 10.8中被弃用,参见第247行。此外,在objc-msg-x86_64.s中,msgSend_fixup似乎只是一条
INT 3
指令(SIGTRAP),这意味着任何试图在现代版本的OS X上使用它的操作系统都可能崩溃。如果您不知道,objective-c运行时是开源的。这类问题通常可以通过查看实现来回答:在本例中,vtable和fixup分派似乎是同义词,而fixup分派在OSX 10.8中被弃用,参见第247行。另外,在objc-msg-x86_64.s中,msgSend_fixup似乎只是一条
INT 3
指令(SIGTRAP),这意味着任何试图在现代版本的OS X上使用它的东西都可能会崩溃。最后一点需要注意的是,Vtable不在对象本身上(如在C++中),而是在对象的类上。因为Objto-C已经有了元类型,所以没有真正的理由在像C++那样的对象级上做VTABLE。这确实意味着有一个额外的间接层次(和缓存未命中),一旦方法缓存出现,这可能对vtables的情况也没有帮助。谢谢您的完整解释。您是否可以推荐一些资源(不包括源代码本身)来跟踪Objective-C中非琐碎的实现更改?@MichałZabielski我不知道。如果我有空闲时间的话,这将是一个有趣的项目。也许有一天,最后一个注意事项是:Vtable不在对象本身上(就像在C++中),而是在对象的类上。因为Objto-C已经有了元类型,所以没有真正的理由在像C++那样的对象级上做VTABLE。这确实意味着有一个额外的间接层次(和缓存未命中),一旦方法缓存出现,这可能对vtables的情况也没有帮助。谢谢您的完整解释。您是否可以推荐一些资源(不包括源代码本身)来跟踪Objective-C中非琐碎的实现更改?@MichałZabielski我不知道。如果我有多余的,这将是一个有趣的项目 #if TARGET_OS_OSX && defined(__x86_64__) // objc_msgSend_fixup() is used for vtable-dispatchable call sites. OBJC_EXPORT void objc_msgSend_fixup(void) __OSX_DEPRECATED(10.5, 10.8, "fixup dispatch is no longer optimized") __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; #if SUPPORT_FIXUP // Fix up old objc_msgSend_fixup call sites for (EACH_HEADER) { message_ref_t *refs = _getObjc2MessageRefs(hi, &count); if (count == 0) continue; if (PrintVtables) { _objc_inform("VTABLES: repairing %zu unsupported vtable dispatch " "call sites in %s", count, hi->fname()); } for (i = 0; i < count; i++) { fixupMessageRef(refs+i); } } ts.log("IMAGE TIMES: fix up objc_msgSend_fixup"); #endif ********************************************************************* * fixupMessageRef * Repairs an old vtable dispatch call site. * vtable dispatch itself is not supported. **********************************************************************/ static void fixupMessageRef(message_ref_t *msg) ENTRY _objc_msgSend_fixup int3 END_ENTRY _objc_msgSend_fixup