文章

iOS 开发中的 inline 函数

前两天在开发的时候遇到这样一个问题:想在 OC 代码中实现一个全局变量,这个变量会根据设备类型取不同的值。代码如下:

1
static CGFloat cardLeftMargin = isIPAD ? 30 : 16;   // 这里的 isIPAD 是个宏

在 swift 中很容易就能实现这个全局变量。但是在 OC 里面,上面的代码编译时报错了, Initializer element is not a compile-time constant.在 OC 里面,全局变量在编译的时候得有个确定的值。解决这个问题有两个方法,一是用宏定义 #define,二是用inline内联函数。

先贴出来使用 inline 函数解决这个问题的方案:

1
2
3
4
5
6
7
// .m file
inline CGFloat cardLeftMargin() {
    return isIPAD ? 30 : 16;
}

// .h file
extern CGFloat cardLeftMargin();

顾名思义,inline函数就是嵌在调用位置的函数。编译器在编译的时候,把inline函数的函数体嵌在每一个调用处。比如,

1
make.left.mas_equalTo(cardLeftMargin());

在编译的时候,就相当于

1
make.left.mas_equalTo(isIPAD ? 30 : 16);

在这里,inline函数和宏非常相像。引入inline函数的主要原因就是为了替代宏定义。如果我们要用宏定义实现上面代码的话,应该是这个样子的:

1
#define cardLeftMargin (isIPAD ? 30.f : 16.f)

可以看到,相比于inline函数,宏定义无法对参数进行类型检查。我想要的是一个CGFloat类型的变量,但是宏定义返回的最多是个float类型的变量。需要我后面再转一下类型,很麻烦,存在一定的局限性。但是inline函数就可以做到类型检测,比较安全

此外,宏需要预编译,而inline函数不需要预编译。可以说,inline函数继承了宏的优点,消除了宏的缺点

本文由作者按照 CC BY-NC-SA 4.0 进行授权