为什么-ObjC链接器标记需要静态库链接类别? (LLVM)(Why is the -ObjC

2019-06-25 13:53发布

对于苹果这样的技术Q&A: http://developer.apple.com/library/mac/#qa/qa1490/_index.html

我认为,编译器可能标志着在编译时在类中定义的方法调用(它知道,他们是在一个类别,而不是主类定义的,因为原型是在@interface Class (Category)部分) -因此它可以建立在“外部的分类方法”的目标文件的表。 然后链接器,做它的正常连接后,应该能够串联/合并和处理来自所有对象“外部的分类方法”表,查找所有链接的框架/库/对象匹配匹配类属符号,那么它可以在没有已经“在”目标的那些拉。

必须有我丢失的东西,但它是什么? 这是为什么不可能?

Answer 1:

链接器将静态库就像一个大的收旧随机件将从中吸取各个部分满足来自链接单元的其他任何符号的请求。

即如果主程序调用_foo_foo只出现在静态库,然后_foo ,与任何相关的符号一起,将被牵扯进来。

然而,当你在一个类别调用一个方法,存在因客观-C的活力没有特定的符号引用。

-ObjC标志告诉的是,正因为如此,它应该抓住从静态库中的所有类别和摔坏的入主二进制链接。


这是一个有点混乱,假设是编译器应该是这个聪明(和,无疑,它应该给在开发工具一级的援助)。 重要的是要记住几件事情是非常重要的:

  • 在头文件中声明任何东西是相当多的链接来临时损失的时间。 符号创建由编译单元,而不是头文件。 头文件几乎生成一个符号,下面进行具体以后创建或链接履行承诺,但在他们自己(或者大家编译单元,并不能创造一个符号 - 每.O - 最终会与副本符号和欢乐会在链接时随之而来)。

  • Objective-C中是完全动态的。 当你说[(id)foo bar]; 中,唯一的要求是bar之前的某处定义的。 没关系,如果它是在所有的实际执行(直到运行反正)。

  • 分类不必具有相应的@implementations; 一类可以用来定义方法可能存在,事实上,之前加入@optional@protocol ,是很普遍的使用上一类NSObject没有(ewwwwww) @implementation说:“嘿,这个可选的方法可能存在于运行”。

  • 编译和链接是完全独立的过程。 编译是所有关于扩大代码,并把它变成可执行的字节库。 链接是所有关于采取这些库并把它们连成的东西,其实是可以运行的,包括解决库之间的所有依赖。 编译器不真正了解的东西如何被链接和链接器没有的事情(即没有产生硬符号)可能已被定义为其中的任何信息。

最终结果?

链接器没有足够的信息来解决依赖性。



文章来源: Why is the -ObjC linker flag needed to link categories in static libraries? (LLVM)