SDK兼容性的代码
2011-11-21 10:42
190 查看
让代码满足兼容性的要求,需要学习下面4项:
1. 类、方法、函数、framework的链接要使用“弱”的。
2. 对不同版本的SDK使用“条件编译”。
3. 注意废弃的API。
4. 在runtime,检查系统的版本、framework的版本。
● 类的“弱链接”。
使用弱链接的类,程序员必须在runtime检查该类是否存在。不事先检查而直接使用,会导致一个runtime binding error,从而终止程序。
检查的最简单的方法是使用“[NSObject class]”方法。但有四个前提:
1> 在写代码时,你先要检查,类的framework是否支持“NS_CLASS_AVAILABLE”宏
2> 工程设置里,base SDK 必须是 iOS 4.2+。<SDKROOT : Base SDK>
3> 对设备的要求,必须是 iOS 3.1+。<IPHONEOS_DEPLOYMENT_TARGET : IOS Deployment Target>
4> 使用的编译器:LLVM-GCC 4.2+、LLVM compiler (Clang) 1.5+
编译示例:
if ([UIPrintInteractionController class]) {
// 可以创建其实例
} else {
// 不支持。想别的辙吧
}
若某iOS工程不能满足上述四个前提,有个替代方案:NSClassFromString。看示例:
Class cls = NSClassFromString (@"NSRegularExpression");
if (cls) {
// 可以创建其实例
} else {
// 不支持。想别的辙吧
}
● 成员函数的“弱链接”。示例:
if ([UIImagePickerController instancesRespondToSelector:@selector (availableCaptureModesForCameraDevice:)]) {
// 可以使用该成员函数
} else {
// 不支持。想别的辙吧
}
● C函数的“弱链接”。示例:
if (CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK (0.1,0.5.0.0,1.0,0.1);
} else {
// 不支持。想别的辙吧
}
警告:必须使用“NULL或nil”进行比较,不能使用操作符“!”求地址的负。
● 多个Base SDK的共存之道:条件编译。
若你的代码要使用多个Base SDK,则必须使用“条件编译”。这就要用到Availability.h里面预定义的一些宏。
在Xcode里,选择File -> Open Quickly,打开Availability.h文件。可以看到这些预定义宏。
示例:
上面的函数 CGColorCreateGenericCMYK 是在Mac OS X v10.5提供的。
假设,很不幸,你安装的Xcode只给你提供了macosx10.4的SDK,怎么办?为了编译通过,把这段代码注释掉吗?
不用的。你只需要用预定义宏即可。
好处是,以后你升级了SDK,或者把该工程拿给别人,一样可以编译,无需任何修改。
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED // 使用Mac OS X的SDK,而非iOS SDK
# if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 // 绝对不能使用__MAC_10_5,而要用数字
if (CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK(0.1,0.5.0.0,1.0,0.1);
} else {
# endif
// 不支持。想别的辙吧
# if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
}
# endif
#endif
__MAC_OS_X_VERSION_MAX_ALLOWED 这个宏由你的Base SDK来自动设置。
对于iOS,对应的宏为:__IPHONE_OS_VERSION_MAX_ALLOWED。
● 对设备的最低版本也用条件编译来区分
在Xcode工程里,设置了“iOS Deployment Target”之后,另外一个宏也就有了值:__IPHONE_OS_VERSION_MIN_REQUIRED。
同上,若你对最低版本也有多个要求,则可使用该宏来做区分。
● 废弃的API
API被标志为“废弃”,意味着不久的将来,该API将消失。虽然不是马上消失,还是要注意的。因为,与“废弃”相伴的,肯定是功能更完善的API的出现。
使用新的API替换废弃的API,这是苹果推荐的作法。
可以使用deprecated关键字搜索你的Build log,即可找到关于废弃API的警告。
● 在运行时检查系统的版本
有时,一个函数会在不同版本的设备上有不同的表现。这时,只检查该API的有无就不能满足要求了。
在iOS设备上,用下面的代码:
NSString *osVersion = [[UIDevice currentDevice] systemVersion];
● 在runtime检查framework的版本
许多framework都可在runtime检查版本,比如Application Kit,可使用NSAppKitVersionNumber。示例:
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_0) {
// [*, 10.0]
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) {
// (10.0, 10.1]
} else {
// (10.1, *)
}
1. 类、方法、函数、framework的链接要使用“弱”的。
2. 对不同版本的SDK使用“条件编译”。
3. 注意废弃的API。
4. 在runtime,检查系统的版本、framework的版本。
● 类的“弱链接”。
使用弱链接的类,程序员必须在runtime检查该类是否存在。不事先检查而直接使用,会导致一个runtime binding error,从而终止程序。
检查的最简单的方法是使用“[NSObject class]”方法。但有四个前提:
1> 在写代码时,你先要检查,类的framework是否支持“NS_CLASS_AVAILABLE”宏
2> 工程设置里,base SDK 必须是 iOS 4.2+。<SDKROOT : Base SDK>
3> 对设备的要求,必须是 iOS 3.1+。<IPHONEOS_DEPLOYMENT_TARGET : IOS Deployment Target>
4> 使用的编译器:LLVM-GCC 4.2+、LLVM compiler (Clang) 1.5+
编译示例:
if ([UIPrintInteractionController class]) {
// 可以创建其实例
} else {
// 不支持。想别的辙吧
}
若某iOS工程不能满足上述四个前提,有个替代方案:NSClassFromString。看示例:
Class cls = NSClassFromString (@"NSRegularExpression");
if (cls) {
// 可以创建其实例
} else {
// 不支持。想别的辙吧
}
● 成员函数的“弱链接”。示例:
if ([UIImagePickerController instancesRespondToSelector:@selector (availableCaptureModesForCameraDevice:)]) {
// 可以使用该成员函数
} else {
// 不支持。想别的辙吧
}
● C函数的“弱链接”。示例:
if (CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK (0.1,0.5.0.0,1.0,0.1);
} else {
// 不支持。想别的辙吧
}
警告:必须使用“NULL或nil”进行比较,不能使用操作符“!”求地址的负。
● 多个Base SDK的共存之道:条件编译。
若你的代码要使用多个Base SDK,则必须使用“条件编译”。这就要用到Availability.h里面预定义的一些宏。
在Xcode里,选择File -> Open Quickly,打开Availability.h文件。可以看到这些预定义宏。
示例:
上面的函数 CGColorCreateGenericCMYK 是在Mac OS X v10.5提供的。
假设,很不幸,你安装的Xcode只给你提供了macosx10.4的SDK,怎么办?为了编译通过,把这段代码注释掉吗?
不用的。你只需要用预定义宏即可。
好处是,以后你升级了SDK,或者把该工程拿给别人,一样可以编译,无需任何修改。
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED // 使用Mac OS X的SDK,而非iOS SDK
# if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 // 绝对不能使用__MAC_10_5,而要用数字
if (CGColorCreateGenericCMYK != NULL) {
CGColorCreateGenericCMYK(0.1,0.5.0.0,1.0,0.1);
} else {
# endif
// 不支持。想别的辙吧
# if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
}
# endif
#endif
__MAC_OS_X_VERSION_MAX_ALLOWED 这个宏由你的Base SDK来自动设置。
对于iOS,对应的宏为:__IPHONE_OS_VERSION_MAX_ALLOWED。
● 对设备的最低版本也用条件编译来区分
在Xcode工程里,设置了“iOS Deployment Target”之后,另外一个宏也就有了值:__IPHONE_OS_VERSION_MIN_REQUIRED。
同上,若你对最低版本也有多个要求,则可使用该宏来做区分。
● 废弃的API
API被标志为“废弃”,意味着不久的将来,该API将消失。虽然不是马上消失,还是要注意的。因为,与“废弃”相伴的,肯定是功能更完善的API的出现。
使用新的API替换废弃的API,这是苹果推荐的作法。
可以使用deprecated关键字搜索你的Build log,即可找到关于废弃API的警告。
● 在运行时检查系统的版本
有时,一个函数会在不同版本的设备上有不同的表现。这时,只检查该API的有无就不能满足要求了。
在iOS设备上,用下面的代码:
NSString *osVersion = [[UIDevice currentDevice] systemVersion];
● 在runtime检查framework的版本
许多framework都可在runtime检查版本,比如Application Kit,可使用NSAppKitVersionNumber。示例:
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_0) {
// [*, 10.0]
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) {
// (10.0, 10.1]
} else {
// (10.1, *)
}
相关文章推荐
- 兼容性(一) - 使代码向前兼容SDK版本
- 兼容性最强的PHP生成缩略图的函数代码(修改版)
- IE和Firefox都兼容性的JS代码书写方式
- js常见兼容性问题举例包含完整代码
- 淘宝SDK扒出来的CURL调用含文件上传代码
- js常见兼容性问题举例包含完整代码
- Javascript浮动广告图片代码,已封装!兼容性强!使用简单!
- java SDK ,上传、读取 基本类型数据通过服务器(客户端代码)
- 用Meta标签代码让360双核浏览器默认极速模式打开网站不是兼容模式(顺带解决很多兼容性问题)
- 微信支付PHP SDK之微信公众号支付代码详解
- 通过代码XML注释与Sandcastle生成SDK文档(进阶篇)
- CSS兼容性解决方案代码片段
- div+css通用兼容性代码整理
- onchange 兼容性代码
- 在sdk的17以上版本webview中js不能调用java代码
- Dialog 1.08 SDK Pxp reporter 代码走读 - 2
- 《VR入门系列教程》之22---GearVR SDK代码剖析
- iOS开发 SDK兼容性
- js 个人整理的兼容性代码
- SDK代码的优化和消息机制的进一步学习