内联如何与外部库一起工作? (迅速)

时间:2016-02-01 10:45:33

标签: ios swift llvm

属性composer require ptrofimov/matchmaker强制编译器内联特定函数。外部库如何在一个项目中内联提供代码?编译器是否实际从库的可执行文件中复制代码段?

1 个答案:

答案 0 :(得分:5)

据我所知,@inline(__always)表示该函数(或类似函数)总是内联的,无论如何。这意味着它的符号在已编译的模块中公开,因此可以由使用该模块的项目内联它们。因此,“总是”。

这基本上是一个未记录的属性,我可以在某些stdlib开发人员的internal documentation中找到唯一的官方参考,甚至没有直接描述其行为。我能找到的最好的非官方文档是Vandad Nahavandipoor's disassembly-confirmed investigation into its behavior,它不会试图确认您所关注的跨模块用例。


Swift 4.2 中,@inlinable@usableFromInlineintroduced来结束这个故事。

我的理解:

  • @inline(__always)强制每次(无论在何处声明或使用)内联函数(等)
  • @inlinable允许将模块中的函数(等)内联到该模块中的调用代码中,或者在编译器认为必要的情况下,内联到使用该模块的代码中
  • @usableFromInline允许模块内部的函数(等)内联到同样位于该模块中的@inlinable调用代码中(如果编译器认为必要的话)。与@inlinable不同,这些必须internal;他们不能成为public

根据Swift.org:

不可攻击

将此属性应用于函数,方法,计算属性,下标,便捷初始化程序或反初始化程序声明,以将该声明的实现公开为模块公共接口的一部分。允许编译器在调用站点用符号实现的副本替换对可插入符号的调用。

可嵌入代码可以与在任何模块中声明的public符号交互,并且可以与在同一模块中声明的带有usableFromInline属性的内部符号交互。不可插入的代码无法与privatefileprivate符号进行交互。

此属性不能应用于嵌套在函数内部的声明或fileprivateprivate声明。即使无法使用此属性标记,在可嵌入函数内部定义的函数和闭包也将隐式不可嵌入。

usableFromInline

将此属性应用于函数,方法,计算属性,下标,初始化程序或反初始化程序声明,以允许将该符号用在与声明相同的模块中定义的可插入代码中。该声明必须具有内部访问级别修饰符。标记为usableFromInline的结构或类只能使用公共类型或usableFromInline作为其属性。标记为usableFromInline的枚举只能将公共类型或usableFromInline用于其案例的原始值和关联值。

类似于public访问级别修饰符,此属性将声明公开为模块公共接口的一部分。与public不同,编译器不允许在模块外的代码中按名称引用标有usableFromInline的声明,即使声明的符号已导出。但是,使用运行时行为,模块外部的代码仍可能能够与声明的符号进行交互。

标记为inlinable属性的声明可从inlinable代码隐式使用。尽管inlinableusableFromInline都可以应用于internal声明,但同时应用这两个属性都是错误的。