Swift内联函数

2,454 阅读2分钟

OC中的内联函数

源码解读

YYKit中的函数方法:

static inline UIEdgeInsets UIEdgeInsetRotateVertical(UIEdgeInsets insets) {
     UIEdgeInsets one;
     one.top = insets.left;
     one.left = insets.bottom;
     one.bottom = insets.right;
     one.right = insets.top;
     return one;
}

分析

引入inline标识符:

  • 使函数称为一个标准的内联函数,函数的代码被放入符号表,在使用时直接进行替换
  • 引入内联函数是为了解决函数调用效率的问题,函数之间调用,是内存地址之间的调用,当函数调用完毕之后还会返回原来函数执行的地址,会有一定的时间开销,内联函数就是为了解决这一问题。

不用inline修饰的函数,汇编时会调用 call 指令,调用call指令就是就需要:

  1. 将下一条指令的所在地址入栈
  2. 并将子程序的起始地址送入PC(于是CPU的下一条指令就会转去执行子程序).

**注:**如果说你的函数体(函数代码)比较长,或者你这个函数存在递归调用,或者说你这个函数包含动态派发,像这些都不会自动内联。

Swift中的内联函数

@inline

第一种

// 永远不会被内联(即使开启了编译器优化)
@inline(never) func test() {
  print("test")
}
  • 加上这个@inline(never),它永远不会被内联

第二种

// 开启编译器优化后,即使代码很长,也会被内联(递归调用函数、动态派发的函数除外)
 @inline(__always) func test () {
     print("test")
 }
  • 必须开启编译器优化
  • 在Debug模式下,加__always是没有用的。
  • 如果函数包含递归调用函数、动态派发,依然是没有效果

关于Swift内联函数基础,可以看: 学习笔记:《iOS高级:Swift入门精讲②》第一节 Swift编程-01➡10 内联函数