iOS 内联函数与宏

459 阅读3分钟

一、内联函数

1.1 内联函数的例子

//此处使用static表明该函数只在该文件中可见,也就是说,在同一个工程中,
//就算在其他文件中也出现同名、同参数的函数也不会引起函数重复定义的错误。
static inline int add(int a,int b)
{
    return a + b;
}
  • 内联函数只是我们向编译器提出的申请,编译器不一定会采用inline形式调用函数;
  • 内联函数不能承载大量代码,如果内联函数的函数体太大,编译器会自动放弃内联;
  • 内联函数中不可以使用循环语句或开关语句(switch语句)
  • 递归函数不可以写成内联函数

1.2 内联函数的优点

1.2.1 内联函数可以提高函数的调用效率

函数调用的效率问题:
1、函数传递参数的拷贝开销;
2、上一个调用函数的上下文的保存。对于传递参数的开销而言,传递的参数越多开销就越大;对于保存当前程序上下文所花费的开销而言,函数越复杂需要花费的开销就越大。

因此应该尽可能地减少不必要的函数调用。

内联函数通过在各个调用它的地方进行复制替换,可以省掉函数调用的开销,是一种以空间换时间的优化方式。

1.2.2 内联函数可以减少重复的代码

通过将重复的代码抽象成内联函数,将会减少重复代码,提高代码的可读性。

1.3 内联函数的缺点

由于内联函数在每一处调用它的地方都要进行代码复制,将会使得程序的总代码量增大,消耗更多的内存空间。

二、宏

2.1 宏的例子

define length 10
  • 宏名一般要大写,末尾不加分号;
  • 通常在文件开头,作用誉为其后的程序;
  • 可以使用#undef命令来终止宏定义的作用域;
  • 宏定义可以嵌套;
  • 字符串中不可以包含宏。

2.1 宏的优点

  • 可以减少重复的代码,提高代码的可读性。
  • 宏展开时只会占用编译时间,不占用运行时间。

2.2 宏的缺点

宏替换在替换函数时可能会有问题

#define Kmax(a, b)  (a) > (b) ? (a) : (b)
//如下调用
int result = Kmax(i, j) + 2 ; 
//结果会变为
result = (i) > (j) ? (i) : (j) + 2 ; 
//显然与我们预期的不一致(应该取i,j的最大值加2

三、两者的比较与选择

3.1 比较

  • 内联函数与宏非常类似,但是效率和安全性都比宏要高。
  • 宏定义,只是简单的表面替换,替换时机为预编译时期;
  • 而内联函数与之不同,内联函数是在编译时进行处理,包括参数、返回值检查等,就像一个真正的函数。

3.2 选择

  • 当函数功能简单(函数调用开销较大,执行开销较小时),可以使用内联函数来规避函数的调用开销,以空间换时间,优化程序的执行效率。
  • 当只进行简单的代码替换时考虑使用宏替换,减少使用宏来替换函数。

四、swift中如何“建议”编译器使用inline呢?

什么都不用做,swift会自己判断的,所以可以认为在swift中不需要考虑显示地使用内联函数来优化程序。