在瞭解宏定義的使用前,須要說明一下合理使用宏定義確實能夠提升程序的可讀性,可是濫用宏定義,也會帶來一些害處。這裏對宏定義使用的優缺點作個簡單的說明:安全
提升了程序的可讀性,同時也方便進行修改,用戶只須要在一處定義,多處使用,修改也只須要修改一處微信
提升程序的運行效率:使用帶參的宏定義既可完成函數調用的功能,又能避免函數的出棧與入棧操做,減小系統開銷,提升運行效率,若是有一個函數會在工程中頻繁使用,能夠考慮一下宏定義函數
因爲是直接嵌入的,因此代碼可能相對多一點spa
嵌套定義過多可能會影響程序的可讀性,並且很容易出錯;code
對帶參的宏而言,因爲是直接替換,並不會檢查參數是否合法,存在安全隱患。orm
宏能夠分爲兩類,一類稱爲對象宏,一類稱爲函數宏cdn
對象宏能夠定義一個量,如圓周率:對象
#define PI 3.1415926
複製代碼
經過宏能夠拿到這個變量:token
float a = PI;
NSLog(@" pi float = %f",a);
int b = PI;
NSLog(@" pi int = %d",b);
複製代碼
打印結果:字符串
2019-03-10 10:30:04.824899+0800 MyObjC[65078:9988537] pi float = 3.141593
2019-03-10 10:30:04.825080+0800 MyObjC[65078:9988537] pi int = 3
複製代碼
可是看一下另一種狀況:
#define width 30+40
int c = width;
NSLog(@" width int = %d",c);
int d = width * 2;
NSLog(@" width int = %d",d);
複製代碼
結果以下:
2019-03-10 10:40:04.571089+0800 MyObjC[65252:10005979] width float = 70
2019-03-10 10:40:04.571200+0800 MyObjC[65252:10005979] width float = 110
複製代碼
爲何*2的結果不是140,是110呢?
由於前面提到過了,宏只是簡單地替換,因此2的時候,實際是30+402
函數宏的做用就相似於一個函數同樣。如:
#define MAX(A,B) A > B ? A : B
int e = MAX(20, 40);
NSLog(@" max int = %d",e);
複製代碼
其結果以下:
2019-03-10 10:46:23.954484+0800 MyObjC[65351:10018292] max float = 40
複製代碼
再來看另一個例子:
#define IS_LEAP_YEAR(y) y%4==0&&y%100!=0||y%400==0
if (IS_LEAP_YEAR(2019)) {
NSLog(@" 2019是潤年");
}else{
NSLog(@" 2019不是潤年");
}
複製代碼
這裏須要注意一個問題,若是宏太長,可使用"/"進行換行
#define IS_LEAP_YEAR2(y) y%4==0&&y%100!=0 \
||y%400==0
複製代碼
這樣即是大大增長了可讀性
在OC中使用字符串都須要使用@"",若是想直接使用字符串能夠添加一個"#":
#define STR(x) # x
NSLog(@" str: %s",STR(aaaa));
2019-03-10 11:31:16.141783+0800 MyObjC[66841:10106049] str: aaaa
複製代碼
再看一個關於##的操做符,鏈接符##用來將兩個token鏈接爲一個token:
#define PARSER(N) printf("token" #N " = %d\n", token##N)
int token64 = 64;
int token32 = 32;
PARSER(64);//用來打印token64
PARSER(32);//用來打印token32
複製代碼
提到可變參數宏,其實可以想到的,最多的即是NSLog。可變參數,能夠利用VA__ARGS進行讀取:
#define NSLog(format, ...) fprintf(stderr, "<%s : %d> %s\n", \
[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, __func__); \
(NSLog)((format), ##__VA_ARGS__); \
fprintf(stderr, "-------\n"); \
mylog(@"這是自定log %d",20)
複製代碼
打印結果以下:
<DefineViewController.m : 58> -[DefineViewController viewDidLoad]
2019-03-10 12:49:18.940393+0800 MyObjC[68204:10216210] 這是自定log 20
-------
複製代碼
本文是來自我公號的文章,歡迎你們關注個人公衆號,更快的更新更友愛的微信羣更全的源碼示例。