美文网首页
【OC梳理】预处理指令

【OC梳理】预处理指令

作者: 忠橙_g | 来源:发表于2017-11-15 15:02 被阅读45次

    预处理指令,就是我们常说的宏定义。在编译器对 C或者 objective-c 进行编译前,编译器会对这些预处理命令进行处理,在编译源程序时,会将定义的内容进行替换编译。
    正确地使用预处理可以简化代码、提高代码的可读性和编写效率。

    使用#define及#undef 执行宏定义

    这里#define的作用是为后面的语句起一个别称,可以使用有意义的名字代替,可以简化编写过程,提高程序可读性。例:

    //将一些常量值定义成有意义的名称,可以提高程序可读性
    //实际项目开发中,常把一些未来可能需要修改的值定义成宏,这样可以避免批量更改代码中的值
    #define PI  3.14159
    
    //将获取屏幕宽度的代码定义成宏,可以简化代码,提升编写效率
    #define KScreenWidth        ([[UIScreen mainScreen] bounds].size.width)
    

    需要注意的是

    宏定义不是C 语句。无需用分号结束,也不要使用=进行赋值。
    宏定义不是变量。不要对宏名称进行赋值。
    编译器处理宏定义,只是进行”查找,替换”,要保证宏定义是正确的。
    执行宏定义后,该宏的作用 域为定义该宏开始,直到该源代码结束,如果想提前结束宏定义,可以使用语句:#undef 宏名称

    带参数的宏定义

    可以在宏定义中使用参数,这样定义的宏更灵活。 格式为:

    #define 宏名称(参数列表) 字符串
    

    例如,将UIColor的创建进行红定义,可以大大简化设置颜色的过程:

    //RGB色值
    #define RGB(r,g,b)          [UIColor colorWithRed:r/255. green:g/255. blue:b/255. alpha:1.]
    #define RGBA(r,g,b,a)       [UIColor colorWithRed:r/255. green:g/255. blue:b/255. alpha:a]
    //十六进制颜色
    #define HEXCOLOR(str)       [UIColor hexFloatColor:str]
    

    需要注意的是

    因为宏定义只是执行简单查找和替换,当传入的参数是个表达式的时候,常会出现一些我们不希望出现的错误。所以,为了编译器能正确处理宏定义,建议将宏定义中的参数用圆括号括起来。如果整个宏定义返回的是数值,可再将整个宏定义的字符串用圆括号括起来。

    使用#ifdef,#ifndef,#else,#endif 执行条件编译

    有时候需要选择性编译——比如对于特定的设备,只编译该设备相关的代码,就可以借助条件编译来完成。
    语法格式1:

    //已定义某个宏,则执行
    #ifdef  宏名称
      //任意语句
    #endif
    
    //如果未定义某个宏,则执行
    #ifndef  宏名称
    //任意语句
    #endif
    

    根据是否定义了指定的宏,选择执行
    语法格式2:

    //已定义某个宏
    #ifdef  宏名称
      //任意语句
    #else 
      //任意语句
    #endif
    
    //如果未定义某个宏
    #ifndef  宏名称
        //任意语句
    #else 
        //任意语句
    #endif
    

    其使用过程类比平常代码中使用的if...else...
    通过条件编译语句,可以较方便地自适应不同的设备。
    通过判断是否debug模式来输出,例:

    //DEBUG  模式下打印日志,当前行
    #ifdef DEBUG
    #define GZCLog(fmt,...)     NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ## __VA_ARGS__);
    #define GZCPrint(...)       printf(__VA_ARGS__)
    #else
    #define GZCLog(...)
    #define GZCPrint(...)
    #endif
    

    使用#if,#elif,#else,#endif 进行条件编译

    对表达式进行判断,根据表达式的值决定是否要编译指定的语句。
    语法格式:

    #if  表达式
      //任意语句
    #elif  表达式
      ...// 可以有零到多个#elif 语句
    #else
      //任意语句
    #endif
    

    条件编译语句和流程控制语句有何区别?

    使用条件编译指令时,不符合条件的程序语句根本不会编译;
    使用普通的分支语句时,所有的代码都被编译成执行性代码,程序运行时再根据需要决定执行哪些语句。
    这就意味着条件编译语句生成的文件更小,执行效率更高。

    #include 与#import

    和C语言相同,#include 指令的作用很简单:将指定的源码插入到当前代码的制定位置。但有个显著的缺点,需要程序员自行判断是否重复导入。但#import可以帮助判断,避免重复导入的问题。
    OC中,#import 中引号和尖括号的作用:

    双引号,告诉预处理程序到当前文件所在路径搜索指定的源文件(也可通过 Xcode 的项目设置来设置预处理的搜索路径);
    而尖括号<>,告诉预处理程序到相应的系统头文件路径中搜索。

    以上就是常用的预处理指令。

    相关文章

      网友评论

          本文标题:【OC梳理】预处理指令

          本文链接:https://www.haomeiwen.com/subject/uowfvxtx.html