您的位置:首页 > 编程语言

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, *)

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: