iOS 宏 常见运用define

    xiaoxiao2026-05-24  7

    简介

    宏定义是C语言提供的三种预处理功能的其中一种,这三种预处理包括:宏定义、文件包含、条件编译

    宏定义又称为宏代换、宏替换,简称“宏”。

    预处理(预编译)工作也叫做宏展开:将宏名替换为字符串。 掌握”宏”概念的关键是“换”。一切以换为前提、做任何事情之前先要换,准确理解之前就要“换”。 即在对相关命令或语句的含义和功能作具体分析之前就要换:

    例如:

    #define Pi 3.1415926

    把程序中出现的Pi全部换成3.1415926

    其它的宏也是同理

    注:宏是没有类型检测的 在使用的时候要注意宏的类型 比如说一个 数字的宏 你不能拿来当成NSString来使用

    不带参数的宏

     

    不带参数的宏,其实就是做一下简单替换

    比如说: // 是否模拟器 #define isSimulator NSNotFound != [[[UIDevice currentDevice] model] rangeOfString:@”Simulator”].location

    在代码中出现 isSimulator的地方都会替换成

    NSNotFound != [[[UIDevice currentDevice] model] rangeOfString:@”Simulator”].location

    这段代码 其实他的值是一个BOOL类型的

    还有

    #define PI 3.1415926 

    出现PI的地方那个都会会变成3.1415926

    这个没什么要多余的,直接过了哒 =)

    带参数的宏

    宏除了一般的字符串替换,还要做参数代换,这个是Macro Magic里面最具有魔法的点

    简单参数宏

    #define ADD(a,b) a+b

    在代码中出现

    int total = ADD(2,3);

    编译的时候就会替换成:int total = 2+3;

    这里面有个坑,要跳过去

    比如定义一个宏:#define S(r) r*r

    代码中使用:S(a+b) 这个时候就会替换成 a+b*a+b 发现问题了吧

    所以正确的宏应该是这样的:#define S(r) (r)*(r)

    这个注意表达式的优先级别就可以绕过这个坑了。

    宏定义Class

     

    这个用法个人感觉比较少见,但是确实很实用,比如定义一个准从相同协议

    下面上一个例子看看 #define CreateClass(className)\ @interface className : NSObject\ -(void)sayHello;\ @end\ @implementation className\ -(void)sayHello \ {\ NSLog(@"Hello,%d",__LINE__);\ }\ @end\

    CreateClass(ABC)

    这样就定义了一个ABC的类 有木有很神奇?

    Block变量弱引用宏

    在使用Block的时候 为了防止循环引用 需要变量弱引用 代码会比较麻烦

    有了宏一切变得简单了 比如: #define WEAK_REF(obj) \ __weak typeof(obj) weak_##obj = obj; \

    注:\ 在宏中是换行的意思,少了它换行会报错; ##是连接符号,将weak与obj这个参数连接成一个字符串

    使用时:

    WEAK_REF(abc);

    Block中用:weak_abc即可

    __LINE__宏

    在Foundation中定义了一个宏叫 __LINE__ 这个宏是告诉你代码在第几行

    你可以在任何一行代码打印__LINE__(NSLog(@”%d”,__LINE__))看看 是不是NSLog所在代码的行数?

    这个大家可以想,如果做后台异常判断的时候把这个代码行数打出来,那不是很容易定位到问题所在地方?

    类似__LINE__这个宏还有 __FILE__   __FUNCTION__

     

    带参数的例子也讲的差不多了,其他的大家发动思维去做吧 =)

     

    条件编译

    条件编译,也是一个魔法

    最常用的就是各种环境 编译出不同的代码,不如一个URL 请求的测试环境和正式环境在开发和线上不是同一个,那一个宏 的条件编译就解决这个问题了

    例子:

    #ifdef ABC

    URL = @”www”;

    #else

    URL = @”wwww”

    #endif

    在来一个例子:

    NSLog问题,一般在线上上不需要打印出来,那通过宏也是可以控制的

    在xxx.pch文件中加入

    #ifdef __OPTIMIZE__ # define NSLog(…) {} #else # define NSLog(…) NSLog(__VA_ARGS__) #endif

    出一个release版本的时候NSLog这个宏就没有任何作用

    解释:

    __OPTIMIZE__ 这个宏在release编译的时候Xcode会定义 把NSLog作为一个宏定义 __VA_ARGS__ 这个是一个可变参数宏

    预处理命令简介

     

    #define 定义一个预处理宏 #undef 取消宏的定义 #include 包含文件命令 #include_next 与#include相似, 但它有着特殊的用途 #if 编译预处理中的条件命令, 相当于C语法中的if语句 #ifdef 判断某个宏是否被定义, 若已定义, 执行随后的语句 #ifndef 与#ifdef相反, 判断某个宏是否未被定义 #elif 若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif之后的语句, 相当于C语法中的else-if #else 与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else之后的语句, 相当于C语法中的else #endif #if, #ifdef, #ifndef这些条件命令的结束标志. defined 与#if, #elif配合使用, 判断某个宏是否被定义 #line 标志该语句所在的行号 # 将宏参数替代为以参数值为内容的字符窜常量 ## 将两个相邻的标记(token)连接为一个单独的标记 #pragma 说明编译器信息 #warning 显示编译警告信息 #error 显示编译错误信息

    好了,讲的比较乱,大家能用多少是多少吧

    转载请注明原文地址: https://ju.6miu.com/read-1310001.html
    最新回复(0)