======================================================
当需要判断iOS系统版本的时候,相信很多人都会这么干:
#define SystemVersion [[UIDevice currentDevice] systemVersion].floatValue
现在告诉屌丝们一个更好的办法就是其实系统已经做了类似的宏定义,不需要我们再去定义了
在Simulator-IOS7.0/usr/include/Availability.h中已经定义了很多系统的宏:
然后使用:
#ifdef __IPHONE_7_0
//iOS7的新特性代码
#endif
或者是使用:
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_7_0
//iOS7的新特性代码
#endif(__IPHONE_OS_VERSION_MAX_ALLOWED 这个定义是在Simulator-IOS7.0/usr/include/AvailabilityInternal.h文件中)
就搞定了。
下面是一些常用的宏:
// 是否5s
#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)
// 是否高清屏
#define isRetina ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)
// 是否模拟器
#define isSimulator (NSNotFound != [[[UIDevice currentDevice] model] rangeOfString:@"Simulator"].location)
// 是否iPad
#define isPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
// 是否iPad
#define someThing (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)? ipad: iphone
宏的基本使用
//定义π值 3.1415926
#define PI 3.1415926
//则在程序用可以如下使用
double i=2*PI*3;
//效果相当于 double i=2*3.1415926*3;
//预处理命令可以定义任何符合格式的形式,例如判断年份是否闰年
#define IS_LEAP_YEAR year%4==0&&year%100!=0||year%400==0
//使用时则可以直接
if(IS_LEAP_YEAR)
//或者可以定义一个参数 1
#define IS_LEAP_YEAR(y) y%4==0&&y%100!=0||y%400==0
//使用时则可以直接
int ys=2012;
if(IS_LEAP_YEAR(ys))
//通常预处理程序定义在一行 如果好分行 比如说太长需要换行 需要使用“/”符号 表示还有下一行,多行分列也是如此,例:
#Define IS_LEAP_YEAR year%4==0&&year%100!=0/
||year%400==0
//宏定义参数后边放一个# 那么在调用该宏时,预处理程序将根据宏参数创建C风格的常量字符串 例: #define STR(x) # x
//将会使得 随后调用的
NSLOG(STR(Programming in Objective-c./n));
//显示结果为 Programming in Objective-c./n
关于#与##的操作符:
<1>.宏定义中字符串化操作符#:
#的功能是将其后面的宏参数进行字符串化操作,意思就是对它所应用的宏变量通过替换后在其左右各加上一个双引号。例如
01#define WARN_IF(EXPR)\
02do {\
03if (EXPR)\
04fprintf(stderr, "Warning: " #EXPR "\n");\
05} while(0)
06
07上面代码中的反斜线\主要用来转译换行符,即屏蔽换行符。
08 09那么如下的代码调用:
10WARN_IF(divider == 0);
11 12将被解析为:
13do {\
14if (divider == 0)\
15fprintf(stderr, "Warning: " "divider == 0" "\n");\ 16} while(0);
注意能够字符串化操作的必须是宏参数,不是随随便便的某个子串(token)都行的。
<2>.宏定义中的连接符##:
连接符##用来将两个token连接为一个token,但它不可以位于第一个token之前or最后一个token之后。注意这里连接的对象只要是token就行,而不一定是宏参数,但是##又必须位于宏定义中才有效,因其为编译期概念(比较绕)。
01#define LINK_MULTIPLE(a, b, c, d) a##_##b##_##c##_##d 02typedef struct _record_type LINK_MULTIPLE(name, company, position, salary); 03/* 04* 上面的代码将被替换为 05* typedef struct _record_type name_company_position_salary; 06*/ 07 08又如下面的例子: 09#define PARSER(N) printf("token" #N " = %d\n", token##N) 10 11int token64 = 64; 12 13如下调用宏: 14PARSER(64); 15 16将被解析为: 17printf("token" "64" " = %d\n", token64); 18 19在obj-c中,如果我有如下定义: 20#define _X(A, B) (A#B) 21#define _XX(A, B) _X([NSString stringWithFormat:@"%@_c", A], B) 22gcc将报错! 23正
======================================================
__IPHONE_OS_VERSION_MIN_REQUIRED
支持最低的系统版本
__IPHONE_OS_VERSION_MAX_ALLOWED
允许最高的系统版本
大多数的文档都没有正确的解释这两个宏定义如何使用
首先明确一个概念,Deploy Target是指编译使用的SDK,BaseSDK是指当前Xcode使用的SDK。
与MIN_REQUIRED和MAX_ALLOWED有关系的是Deploy Target。
举个例子来说明:
比如SDK 3.x
__IPHONE_OS_VERSION_MIN_REQUIRED==__IPHONE_3_0
__IPHONE_OS_VERSION_MAX_ALLOWED==__IPHONE_3_x
通常,__IPHONE_OS_VERSION_MAX_ALLOWED可以代表当前SDK的版本,而__IPHONE_OS_VERSION_MIN_REQUIRED则是当前SDK支持的最低版本(换句话说就是能够使用的方法的最低版本)。
在UIDevice的接口中,有一个如下判断。
typedef NS_ENUM(NSInteger, UIUserInterfaceIdiom)
{
#if __IPHONE_3_2 <= __IPHONE_OS_VERSION_MAX_ALLOWED
UIUserInterfaceIdiomPhone, // iPhone and iPod touch style UI
UIUserInterfaceIdiomPad, // iPad style UI
#endif
};
“__IPHONE_OS_VERSION_MAX_ALLOWED>=__IPHONE_3_2”指最高系统版本>=3.2,也就是说需要3.2及以上的SDK才会编译此处。
当然,根据红字出的理解,这句话还可以翻译为“需要系统版本>=3.2”。
开始的时候,我错误的认为应该写成“ __IPHONE_OS_VERSION_MIN_REQUIRED >=__IPHONE_3_2”,是因为不理解iOS SDK的编译规则。
举个例子,我在用__IPHONE_3_2的SDK编译的时候,我能够使用3.0的方法,也就是说3.0-3.2的方法我们都能用,但是3.0以前版本的方法就不行了。
所以,__IPHONE_OS_VERSION_MAX_ALLOWED用来判断是否当前版本“开始”支持或具有某些功能;__IPHONE_OS_VERSION_MIN_REQUIRED用来判断是否当前版本“仍然”支持或具有某些功能。
所以,__IPHONE_OS_VERSION_MIN_REQUIRED >=__IPHONE_3_2方在这里是不对的。不知道什么版本的SDK才会把自己的支持范围裁剪至__IPHONE_3_2呢。
============================================================
//设备型号
#define IS_IPAD [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
#define IS_IPHONE [[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone
#define IS_IPHONE_4 (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )480) < DBL_EPSILON )
#define IS_IPHONE_5 (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )568) < DBL_EPSILON )
#define IS_IPHONE_6 (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )667) < DBL_EPSILON )
#define IS_IPHONE_6_PLUS (fabs((double)[[UIScreen mainScreen] bounds].size.height - (double )960) < DBL_EPSILON )
//系统版本
#define IS_IOS_VERSION floorf([[UIDevice currentDevice].systemVersion floatValue]
#define IS_IOS_5 floorf([[UIDevice currentDevice].systemVersion floatValue]) ==5.0 ? 1 : 0
#define IS_IOS_6 floorf([[UIDevice currentDevice].systemVersion floatValue]) ==6.0 ? 1 : 0
#define IS_IOS_7 floorf([[UIDevice currentDevice].systemVersion floatValue]) ==7.0 ? 1 : 0
#define IS_IOS_8 floorf([[UIDevice currentDevice].systemVersion floatValue]) ==8.0 ? 1 : 0
#define IS_IOS_9 floorf([[UIDevice currentDevice].systemVersion floatValue]) ==9.0 ? 1 : 0
//物理屏幕尺寸
#define IH_DEVICE_HEIGHT [[UIScreen mainScreen] bounds].size.height
#define IH_DEVICE_WIDTH [[UIScreen mainScreen] bounds].size.width
//自定义的NSLog
#ifdef DEBUG
#define XSLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#define YYLog(FORMAT, ...) fprintf(stderr,"%s:%d\t%s\n",[[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, [[NSString stringWithFormat:FORMAT, ##__VA_ARGS__] UTF8String]);
#else
#define XSLog(FORMAT, ...) nil;
#define YYLog(FORMAT, ...) nil;
#endif
==================================================
iOS开发常用宏定义
iOS开发中常常需要获取屏幕宽度高度,为view设置颜色,为imgagView设置图片等,我们都可定义一些宏,随时都可拿来使用,方便开发
#ifndef FingerTips_Macro_Config_h
#define FingerTips_Macro_Config_h
//获取屏幕 宽度、高度
#define SCREEN_WIDTH ([UIScreen mainScreen].bounds.size.width)
#define SCREEN_HEIGHT ([UIScreen mainScreen].bounds.size.height)
//DEBUG 模式下打印日志,当前行
#ifdef DEBUG
#define NSLog(format, ...) do { fprintf(stderr, "<%s : %d> %s\n", [[[NSString stringWithUTF8String:__FILE__] lastPathComponent] UTF8String], __LINE__, __func__); (NSLog)((format), ##__VA_ARGS__); fprintf(stderr, "-------\n"); } while (0)
#else
#define NSLog(...)
#endif
//判断是否 Retina屏、设备是否%fhone 5、是否是iPad
#define isRetina ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 960), [[UIScreen mainScreen] currentMode].size) : NO)
#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)
#define isPad (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
//获取系统版本
#define IOS_VERSION [[[UIDevice currentDevice] systemVersion] floatValue]
#define CurrentSystemVersion [[UIDevice currentDevice] systemVersion]
//判断是真机还是模拟器
#if TARGET_OS_IPHONE
//iPhone Device
#endif
#if TARGET_IPHONE_SIMULATOR
//iPhone Simulator
#endif
//检查系统版本
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
//读取本地图片
#define LOADIMAGE(file,ext) [UIImage imageWithContentsOfFile:[[NSBundle mainBundle]pathForResource:file ofType:ext]]
//定义UIImage对象
#define IMAGE(imageName) [UIImage imageNamed:[NSString stringWithFormat:@"%@",imageName]]
// rgb颜色转换(16进制->10进制)
#define UIColorFromRGB(rgbValue) [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 green:((float)((rgbValue & 0xFF00) >> 8))/255.0 blue:((float)(rgbValue & 0xFF))/255.0 alpha:1.0]
// 获取RGB颜色
#define RGBA(r,g,b,a) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:a]
#define RGB(r,g,b) RGBA(r,g,b,1.0f)
// 获取屏幕大小
#define kDeviceWidth [UIScreen mainScreen].bounds.size.width
#define KDeviceHeight [UIScreen mainScreen].bounds.size.height
#define IS_IOS7 (([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)? (YES):(NO))
#define IS_IOS6 (([[[UIDevice currentDevice] systemVersion] floatValue] >= 6.0)? (YES):(NO))
#define IS_4INCH ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)
//释放内存
#define RELEASE_SAFE(_Pointer) do{[_Pointer release],_Pointer = nil;}while(0)
#endif