iOS 开发中的 inline 函数
前两天在开发的时候遇到这样一个问题:想在 OC 代码中实现一个全局变量,这个变量会根据设备类型取不同的值。代码如下:
static CGFloat cardLeftMargin = isIPAD ? 30 : 16; // 这里的 isIPAD 是个宏
在 swift 中很容易就能实现这个全局变量。但是在 OC 里面,上面的代码编译时报错了, Initializer element is not a compile-time constant
.在 OC 里面,全局变量在编译的时候得有个确定的值。解决这个问题有两个方法,一是用宏定义 #define
,二是用inline
内联函数。
先贴出来使用 inline
函数解决这个问题的方案:
// .m file
inline CGFloat cardLeftMargin() {
return isIPAD ? 30 : 16;
}
// .h file
extern CGFloat cardLeftMargin();
顾名思义,inline
函数就是嵌在调用位置的函数。编译器在编译的时候,把inline
函数的函数体嵌在每一个调用处。比如,
make.left.mas_equalTo(cardLeftMargin());
在编译的时候,就相当于
make.left.mas_equalTo(isIPAD ? 30 : 16);
在这里,inline
函数和宏非常相像。引入inline
函数的主要原因就是为了替代宏定义。如果我们要用宏定义实现上面代码的话,应该是这个样子的:
#define cardLeftMargin (isIPAD ? 30.f : 16.f)
可以看到,相比于inline
函数,宏定义无法对参数进行类型检查。我想要的是一个CGFloat
类型的变量,但是宏定义返回的最多是个float
类型的变量。需要我后面再转一下类型,很麻烦,存在一定的局限性。但是inline
函数就可以做到类型检测,比较安全
此外,宏需要预编译,而inline
函数不需要预编译。可以说,inline
函数继承了宏的优点,消除了宏的缺点