一 基本用法
1.
宏定义需要加括号的两种情况
:
(1)
如果宏的替换列表中带有运算符
,
那么使用要将替换列表放到括号中。例如
#define MAX_VALUE(X,Y) ((X) > (Y) ? (X) : (Y))
(2)如果宏有参数,每次参数在替换列表中出现时都要放在括号中。同上
#define MAX_VALUE(X,Y) ((X) > (Y) ? (X) : (Y))
//
求两个数中的最大值
2.#
运算符和
##
运算符
(1)
出现在宏定义中的
#
运算符把跟在其后的参数转换成一个字符串。有时把这种用法的
#
称为字符串化运算符。例如:
#define PASTE(n) "adhfkj"#n
main()
{
printf("%s\n",PASTE(15));
main()
{
printf("%s\n",PASTE(15));
}
宏定义中的
#
运算符告诉预处理程序,把源代码中任何传递给该宏的参数转换成一个字符串。所以输出应该是
adhfkj15
。
针对
Window,dos,os2
不同的系统对
WIDTH
进行不同的定义
单独一行的
#
是空指令
#ifdef WINDOWS
#
#define WIDTH 375
#
#elif defined(DOS)
#
#define WIDTH 414
#
#elif defined(OS)
#
#define WIDTH 320
#
#else
#
//#error no sysytem;
#
#
#define WIDTH 375
#
#elif defined(DOS)
#
#define WIDTH 414
#
#elif defined(OS)
#
#define WIDTH 320
#
#else
#
//#error no sysytem;
#
#endif
(2)##运算符用于把参数连接到一起。预处理程序把出现在##两侧的参数合并成一个符号。看下面的例子:
#define NUM(a,b,c) a##b##c
#define STR(a,b,c) a##b##c
main()
{
printf("%d\n",NUM(1,2,3));
printf("%s\n",STR("aa","bb","cc"));
}
最后程序的输出为 :
123
aabbcc
#define STR(a,b,c) a##b##c
main()
{
printf("%d\n",NUM(1,2,3));
printf("%s\n",STR("aa","bb","cc"));
}
最后程序的输出为 :
123
aabbcc
#define IMAGE_NAME(NAME) @
"image_name"
#NAME
// IMAGE_NAME(3)=image_name3
#define STR(NAME,AGE,SEX) @
"
名字
:"
#NAME@
".
年龄
:"
#AGE@
".
性别
:"
#SEX
//
名字
:@“
王五
".
年龄
:24.
性别
:@"
男
"
3.
取消宏定义
#undef NUM1
4.
复杂宏的定义
#define NSLOG_ARRAY_OR_DICT(ARRAY,DICT) (NSLog(@
"array = %@,dict = %@"
,[(ARRAY) description],[(DICT) description]));
// 设计技巧 :dowhile 中出现 ;
#define NSLOG_ARRAY_OR_DICT2(ARRAY,DICT) do {int a = 1 ;NSLog(@ "a = %d" ,a);NSLog(@ "array = %@,dict = %@" ,[(ARRAY) description],[(DICT) description]);}while( 0 )
// 设计技巧 :dowhile 中出现 ;
#define NSLOG_ARRAY_OR_DICT2(ARRAY,DICT) do {int a = 1 ;NSLog(@ "a = %d" ,a);NSLog(@ "array = %@,dict = %@" ,[(ARRAY) description],[(DICT) description]);}while( 0 )
5.
条件编译
args...
表示有多个参数
(1)
打印信息
#define DEBUG
1
#if DEBUG
#define MY_NSLog(fmt,args...) NSLog(@fmt,##args)
#else
#define MY_NSLog(fmt,args...)
#if DEBUG
#define MY_NSLog(fmt,args...) NSLog(@fmt,##args)
#else
#define MY_NSLog(fmt,args...)
#endif
二 常用宏定义
ZBConst.h 宏定义文件集合(包含以下宏定义)==>
ZBHttpConst.h 网络相关宏定义(推荐用const常量代替)
ZBNotificationConst.h 通知相关宏定义(推荐用const常量代替)
ZBDeviceConst.h 系统相关宏定义
ZBStringConst.h 字符串相关宏定义
ZBDefineConst.h 自定义宏
1.系统相关宏定义
/** 1.
设备状态条
,
导航栏
,tabbar
高度
*/
#define ZB_HEIGHT_STATUSBAR 20.f // 状态条高度
#define ZB_HEIGHT_NAVIGATIONBAR 44.f // 导航栏高度
#define ZB_HEIGHT_TABBAR 49.f // tabbar 高度
/** 2. 设备屏幕宽度和高度 ( 支持横屏 ) */
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 // 当前 Xcode 支持 iOS8 及以上
#define ZB_SCREEN_WIDTH ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]?[UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale:[UIScreen mainScreen].bounds.size.width)
#define ZB_SCREEN_HEIGHT ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]?[UIScreen mainScreen].nativeBounds.size.height/[UIScreen mainScreen].nativeScale:[UIScreen mainScreen].bounds.size.height)
#define ZB_SCREEN_SIZE ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]?CGSizeMake([UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale,[UIScreen mainScreen].nativeBounds.size.height/[UIScreen mainScreen].nativeScale):[UIScreen mainScreen].bounds.size)
#else
#define ZB_SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define ZB_SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define ZB_SCREEN_SIZE [UIScreen mainScreen].bounds.size
#endif
/**
* 3. 设备类型
* 设备屏幕高度 :IPHONE4(iPhone4,iPhone4s)480;IPHONE5(iPhone5,iPhone5s)568;IPHONE6 667;IPHONE6PLUS 736.
* EPSILON 是最小误差 ,DBL_EPSILON 是双浮点型 (double) 最小误差 , 是 EPSILON+X 不等于 X 的最小的正数
*/
#if TARGET_IPHONE_SIMULATOR // 模拟器
#define IPHONE4 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 480 ) < DBL_EPSILON )
#define IPHONE5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 568 ) < DBL_EPSILON )
#define IPHONE6 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 667 ) < DBL_EPSILON )
#define IPHONE6PLUS ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 736 ) < DBL_EPSILON )
#elif TARGET_OS_IPHONE // 真机
#define IPHONE4 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 480 ) < DBL_EPSILON )
#define IPHONE5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 568 ) < DBL_EPSILON )
#define IPHONE6 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 667 ) < DBL_EPSILON )
#define IPHONE6PLUS ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 736 ) < DBL_EPSILON )
#endif
// 判断是否为 iPhone
#define ZB_IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
// 判断是否为 iPad
#define ZB_IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// 判断是否为 ipod
#define ZB_IS_IPOD ([[[UIDevice currentDevice] model] isEqualToString:@ "iPod touch" ])
/**
* 4. 设备系统版本
*/
#define iOS6_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0 )
#define iOS7_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0 )
#define iOS8_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0 )
#define iOS9_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0 )
#define iOS7_0 ([[UIDevice currentDevice].systemVersion floatValue] == 7.0 )
#define iOS7_1 ([[UIDevice currentDevice].systemVersion floatValue] == 7.1 )
#define iOS8_0 ([[UIDevice currentDevice].systemVersion floatValue] == 8.0 )
#define iOS8_1 ([[UIDevice currentDevice].systemVersion floatValue] == 8.1 )
#define iOS8_2 ([[UIDevice currentDevice].systemVersion floatValue] == 8.2 )
#define iOS8_3 ([[UIDevice currentDevice].systemVersion floatValue] == 8.3 )
#define iOS9_0 ([[UIDevice currentDevice].systemVersion floatValue] == 9.0 )
#define iOS9_1 ([[UIDevice currentDevice].systemVersion floatValue] == 7.1 )
/** 5. 获取 temp, 沙盒 Document, 沙盒 Cache 目录 */
#define ZB_PATH_TEMP NSTemporaryDirectory()
#define ZB_PATH_DOCUMENT [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
#define ZB_PATH_CACHE [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]
/** 6.ARC/MRC */
#if __has_feature(objc_arc)
// ARC
#else
// MRC
#define ZB_HEIGHT_STATUSBAR 20.f // 状态条高度
#define ZB_HEIGHT_NAVIGATIONBAR 44.f // 导航栏高度
#define ZB_HEIGHT_TABBAR 49.f // tabbar 高度
/** 2. 设备屏幕宽度和高度 ( 支持横屏 ) */
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 // 当前 Xcode 支持 iOS8 及以上
#define ZB_SCREEN_WIDTH ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]?[UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale:[UIScreen mainScreen].bounds.size.width)
#define ZB_SCREEN_HEIGHT ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]?[UIScreen mainScreen].nativeBounds.size.height/[UIScreen mainScreen].nativeScale:[UIScreen mainScreen].bounds.size.height)
#define ZB_SCREEN_SIZE ([[UIScreen mainScreen] respondsToSelector:@selector(nativeBounds)]?CGSizeMake([UIScreen mainScreen].nativeBounds.size.width/[UIScreen mainScreen].nativeScale,[UIScreen mainScreen].nativeBounds.size.height/[UIScreen mainScreen].nativeScale):[UIScreen mainScreen].bounds.size)
#else
#define ZB_SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define ZB_SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define ZB_SCREEN_SIZE [UIScreen mainScreen].bounds.size
#endif
/**
* 3. 设备类型
* 设备屏幕高度 :IPHONE4(iPhone4,iPhone4s)480;IPHONE5(iPhone5,iPhone5s)568;IPHONE6 667;IPHONE6PLUS 736.
* EPSILON 是最小误差 ,DBL_EPSILON 是双浮点型 (double) 最小误差 , 是 EPSILON+X 不等于 X 的最小的正数
*/
#if TARGET_IPHONE_SIMULATOR // 模拟器
#define IPHONE4 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 480 ) < DBL_EPSILON )
#define IPHONE5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 568 ) < DBL_EPSILON )
#define IPHONE6 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 667 ) < DBL_EPSILON )
#define IPHONE6PLUS ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 736 ) < DBL_EPSILON )
#elif TARGET_OS_IPHONE // 真机
#define IPHONE4 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 480 ) < DBL_EPSILON )
#define IPHONE5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 568 ) < DBL_EPSILON )
#define IPHONE6 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 667 ) < DBL_EPSILON )
#define IPHONE6PLUS ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double ) 736 ) < DBL_EPSILON )
#endif
// 判断是否为 iPhone
#define ZB_IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
// 判断是否为 iPad
#define ZB_IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// 判断是否为 ipod
#define ZB_IS_IPOD ([[[UIDevice currentDevice] model] isEqualToString:@ "iPod touch" ])
/**
* 4. 设备系统版本
*/
#define iOS6_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 6.0 )
#define iOS7_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 7.0 )
#define iOS8_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0 )
#define iOS9_LATER ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0 )
#define iOS7_0 ([[UIDevice currentDevice].systemVersion floatValue] == 7.0 )
#define iOS7_1 ([[UIDevice currentDevice].systemVersion floatValue] == 7.1 )
#define iOS8_0 ([[UIDevice currentDevice].systemVersion floatValue] == 8.0 )
#define iOS8_1 ([[UIDevice currentDevice].systemVersion floatValue] == 8.1 )
#define iOS8_2 ([[UIDevice currentDevice].systemVersion floatValue] == 8.2 )
#define iOS8_3 ([[UIDevice currentDevice].systemVersion floatValue] == 8.3 )
#define iOS9_0 ([[UIDevice currentDevice].systemVersion floatValue] == 9.0 )
#define iOS9_1 ([[UIDevice currentDevice].systemVersion floatValue] == 7.1 )
/** 5. 获取 temp, 沙盒 Document, 沙盒 Cache 目录 */
#define ZB_PATH_TEMP NSTemporaryDirectory()
#define ZB_PATH_DOCUMENT [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject]
#define ZB_PATH_CACHE [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]
/** 6.ARC/MRC */
#if __has_feature(objc_arc)
// ARC
#else
// MRC
#endif
2.自定义宏
/** 1.
颜色字体
*/
#define ZB_COLOR_HEX(x) ([UIColor colorWithHexColor:(x)])
#define ZB_COLOR(r,g,b) ([UIColor colorWithRed:(r)/ 255.0 green:(g)/ 255.0 blue:(b)/ 255.0 alpha: 255 / 255.0 ])
#define ZB_COLOR_ALPHA(r,g,b,a) ([UIColor colorWithRed:(r)/ 255.0 green:(g)/ 255.0 blue:(b)/ 255.0 alpha:(a)])
#define ZB_COLOR_RANDOM ([UIColor colorWithRed:arc4random_uniform( 256 )/ 255.0 green:arc4random_uniform( 256 )/ 255.0 blue:arc4random_uniform( 256 )/ 255.0 alpha: 1.0 ])
#define ZB_FONT(x) ([UIFont systemFontOfSize:(x)])
/** 2. 空值判断 */
#define ZB_IS_EMPTY_STR(_str) (((_str) == nil) || ([(_str) isEqual:[NSNull null]]) ||([(_str)isEqualToString:@ "" ]))
#define ZB_IS_EMPTY_ARR(_arr) (((_arr) == nil) || ([(_arr) isEqual:[NSNull null]]) ||([(_arr) count] == 0 ))
/** 3. 单例 */
// 声明单例
#undef ZB_SINGLETON_DEFINE
#define ZB_SINGLETON_DEFINE( __class ) \
+ (__class *)sharedInstance;
// 实现单例
#undef ZB_SINGLETON_IMPLEMENT
#define ZB_SINGLETON_IMPLEMENT( __class ) \
+ (__class *)sharedInstance \
{ \
static __class * __singleton__ = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
__singleton__ = [[__class alloc] init]; \
}); \
return __singleton__; \
}
/** 4. 打印日志 */
#ifdef DEBUG
#define ZBLog(...) NSLog(__VA_ARGS__)
#define ZB_LOG_INT(N) NSLog(@ "%d" ,(N))
#define ZB_LOG_FLOAT(F) NSLog(@ "%f" ,(F))
#define ZB_LOG_INTEGER(I) NSLog(@ "%ld" ,(long)(I))
#else
#define ZBLog(...)
#define ZB_LOG_INT(N)
#define ZB_LOG_FLOAT(F)
#define ZB_LOG_INTEGER(I)
#endif
/** 5.weakself/strongself */
#define ZB_WEAK_SELF(type) __weak typeof(type) weak##type = type;
#define ZB_STRONG_SELF(type) __strong typeof(weak##type) strong##type = weak##type;
/** 6.GCD */
// GCD - 一次性执行
#define ZB_DISPATCH_ONCE_BLOCK(onceBlock) static dispatch_once_t onceToken; dispatch_once(&onceToken, onceBlock);
// GCD - 在 Main 线程上运行
#define ZB_DISPATCH_MAIN_THREAD(mainQueueBlock) dispatch_async(dispatch_get_main_queue(), mainQueueBlock);
// GCD - 开启异步线程
#define ZB_COLOR_HEX(x) ([UIColor colorWithHexColor:(x)])
#define ZB_COLOR(r,g,b) ([UIColor colorWithRed:(r)/ 255.0 green:(g)/ 255.0 blue:(b)/ 255.0 alpha: 255 / 255.0 ])
#define ZB_COLOR_ALPHA(r,g,b,a) ([UIColor colorWithRed:(r)/ 255.0 green:(g)/ 255.0 blue:(b)/ 255.0 alpha:(a)])
#define ZB_COLOR_RANDOM ([UIColor colorWithRed:arc4random_uniform( 256 )/ 255.0 green:arc4random_uniform( 256 )/ 255.0 blue:arc4random_uniform( 256 )/ 255.0 alpha: 1.0 ])
#define ZB_FONT(x) ([UIFont systemFontOfSize:(x)])
/** 2. 空值判断 */
#define ZB_IS_EMPTY_STR(_str) (((_str) == nil) || ([(_str) isEqual:[NSNull null]]) ||([(_str)isEqualToString:@ "" ]))
#define ZB_IS_EMPTY_ARR(_arr) (((_arr) == nil) || ([(_arr) isEqual:[NSNull null]]) ||([(_arr) count] == 0 ))
/** 3. 单例 */
// 声明单例
#undef ZB_SINGLETON_DEFINE
#define ZB_SINGLETON_DEFINE( __class ) \
+ (__class *)sharedInstance;
// 实现单例
#undef ZB_SINGLETON_IMPLEMENT
#define ZB_SINGLETON_IMPLEMENT( __class ) \
+ (__class *)sharedInstance \
{ \
static __class * __singleton__ = nil; \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
__singleton__ = [[__class alloc] init]; \
}); \
return __singleton__; \
}
/** 4. 打印日志 */
#ifdef DEBUG
#define ZBLog(...) NSLog(__VA_ARGS__)
#define ZB_LOG_INT(N) NSLog(@ "%d" ,(N))
#define ZB_LOG_FLOAT(F) NSLog(@ "%f" ,(F))
#define ZB_LOG_INTEGER(I) NSLog(@ "%ld" ,(long)(I))
#else
#define ZBLog(...)
#define ZB_LOG_INT(N)
#define ZB_LOG_FLOAT(F)
#define ZB_LOG_INTEGER(I)
#endif
/** 5.weakself/strongself */
#define ZB_WEAK_SELF(type) __weak typeof(type) weak##type = type;
#define ZB_STRONG_SELF(type) __strong typeof(weak##type) strong##type = weak##type;
/** 6.GCD */
// GCD - 一次性执行
#define ZB_DISPATCH_ONCE_BLOCK(onceBlock) static dispatch_once_t onceToken; dispatch_once(&onceToken, onceBlock);
// GCD - 在 Main 线程上运行
#define ZB_DISPATCH_MAIN_THREAD(mainQueueBlock) dispatch_async(dispatch_get_main_queue(), mainQueueBlock);
// GCD - 开启异步线程
#define ZB_DISPATCH_GLOBAL_QUEUE_DEFAULT(globalQueueBlock) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
0
), globalQueueBlock);