原文地址:https://developer.apple.com/library/mac/documentation/DeveloperTools/Conceptual/cross_development/Using/using.html#//apple_ref/doc/uid/20002000-SW5
使用
基于 SDK 的
开发
Mac
开发者
库
的
开发人员
搜索
SDK
兼容性
指南 》
NextPrevious
使用
基于 SDK 的
开发
这
一
章
描述了
基于 SDK 的
开发
技术
,在
解释
你
如何
你
Xcode
项目
中
使用
:
使用
弱
关联
的
类
、
方法
和
函数
来
支持
在
多个
版本
的
操作系统
上
运行
弱
链接
整个
框架
有条件地
为
不同
Sdk
的
编译
查找
代码
中
的
过时
的
Api
服务
的
使用
在
运行
时
确定
操作系统
版本
或
框架
版本
,
对
弱
链接
的
背景
,
读
弱
链接
和
苹果
框架
。
在
iOS
中
使用
弱
链接
类
如果
你
Xcode
项目
使用
弱
链接
的
类
,
您
必须
在
运行
时
使用
这些
东西
之前
确保
这些
类
的
可用性
。
试图
使用
一个
不可用
的
类
可能会
生成
运行时
绑定
错误
从
动态
链接
器
可能
终止
相应
的
过程
。
使用
iOS
4.2
或
更高版本
基地
SDK
的
Xcode
项目
应
使用
NSObject
类
方法
以
在
运行
时
检查
弱
关联
的
类
的
可用性
。
这
种
简单
、
高效
的
机制
利用
NS_CLASS_AVAILABLE
类
可用性
的
宏
,
可
用于
大多数
框架
在
iOS
。
重要事项
:
检查
最
新
的
iOS
发行
说明
的
框架
还
不
支持
NS_CLASS_AVAILABLE
宏
的
列表
。
为
支持
NS_CLASS_AVAILABLE
宏
的
iOS
框架
,
conditionalize
弱
关联
的
类
的
代码
,
如
下面
的
示例
所
示
:
if ([UIPrintInteractionController class]) { |
// Create an instance of the class and use it. |
} else { |
// Alternate code path to follow when the |
// class is not available. |
} |
这
是
因为
如果
弱
链接
的
类
不
是
可用
的
向
它
发送
一
条消息
就
像
发送
消息
到
零
。
如果
子类
弱
链接
类
和
超类
是
不可用
,
然后
子类
也
显示
为
不可用
。
要
使用
的
类
方法
,
如下
所示
在这里
,
您
需要
确保
做
多
个
框架
支持
NS_CLASS_AVAILABLE
宏
。
您
还
必须
配置
某些
项目
设置
。
与
这些
所需
的
设置
,
在
地方
,
前面
的
代码
安全
测试
可用性
的
一
类
,
即使
在
iOS
中
的
类
不
是
当前
版本
上
运行
。
这些
设置
如下
所示
:
你
Xcode
项目
基地
SDK
必须
iOS
4.2
或
更高版本
。
这
在
生成
设置
编辑器
中
设置
的
名称
是
SDKROOT
(基地
SDK)。
部署
目标
为
您
的
项目
必须
是
iOS
3.1
或
更高版本
。
此
设置
的
名称
是
MACOSX_DEPLOYMENT_TARGET
(OS
X
部署
目标)。
编译器
为
您
的
项目
必须
是
LLVM GCC
4.2
编译器
或
更高版本
,
或
LLVM
编译器
(铁门)
1.5
或
更高版本
。
此
设置
的
名称
是
GCC_VERSION
(C/c + +
编译器
版本)。
你
必须
确保
任何
不适
用于
您
的
项目
部署
目标
的
框架
弱
,
链接
,
而
不
是
所需
的性能
。
请参阅
弱
到
整个
框架
链接
和
链接
库
和
框架
Xcode
项目
管理
指南 》
。
有关
使用
Xcode
的
信息
构建
设置
编辑器
,
请参阅
Xcode
项目
管理
指南
中
的
建材
产品
。
在
OS
X
(和
不
符合
条件
刚刚
上市
的
一整套
的
iOS
项目
),
不能
使用
的
类
方法
来
确定
一个
弱
链接
的
类
可用
。
相反
,
使用
NSClassFromString
函数
在
类似
于
以下内容
的
代码
:
Class cls = NSClassFromString (@"NSRegularExpression"); |
if (cls) { |
// Create an instance of the class and use it. |
} else { |
// Alternate code path to follow when the |
// class is not available. |
} |
使用
弱
链接
的
方法
、
函数
和
符号
如果
您
的
项目
使用
弱
链接
的
方法
、
函数
或
外部
符号
,
则
必须
在
运行
时
使用
这些
东西
之前
确保
它们
的
可用性
。
如果
你
试图
使用
一个
不可用
的
项目
,
动态
链接器
可能会
生成
运行时
绑定
错误
并
终止
相应
的
过程
。
假设
您
设置
基地
SDK
到
iOS
4.0
Xcode
项目
中
。
这
允许
您
的
代码
以
使用
该
版本
的
操作系统
中
的
功能
,在
该
版本
中
运行
时
。
此外
假定
您
希望
您
的
软件
运行
在
iOS
3.1
,
即使
它
不能
在
该
版本
的
操作系统
中
使用
较新
的
功能
。
这
允许
通过
将
部署
目标
设置
为
早期
版本
的
操作系统
。
在
目标 C,
instancesRespondToSelector
:
方法
就可以
告诉
你
是否
给定
的
方法
选择
器
可用
。
例如
,
若要
使用
availableCaptureModesForCameraDevice
:
方法
,
第一次
在
iOS
4.0
中
可用
,
您
可以
使用
类似
以下
的
代码
:
清单
3-1
检查
目标 C
方法
的
有效性
if ([UIImagePickerController instancesRespondToSelector: |
@selector (availableCaptureModesForCameraDevice:)]) { |
// Method is available for use. |
// Your code can check if video capture is available and, |
// if it is, offer that option. |
} else { |
// Method is not available. |
// Alternate code to use only still image capture. |
} |
当
您
的
代码
在
iOS
4.0
或
更高版本
中
运行
时
,
它
可以
调用
availableCaptureModesForCameraDevice
:
要
确定
如果
视频
捕获
设备
上
的
可用
。
当
它
在
iOS
3.1
中
运行
时
,
但是
,
它
必须
承担
捕获
图像
仍然
只
是
可用
。
如果
你
具有
各种
设置
生成
此
代码
,
您
会
看到
以下
结果
:
如果
您
指定
iphoneos3.1
基地
SDK
设置
:
生成
将
失败
,
因为
availableCaptureModesForCameraDevice
:
在
该
系统
版本
中
未
定义
的
方法
。
如果
你
指定
iphoneos4.0
,
基地
SDK
设置
,
然后
将
部署
目标
设置
为
:
iphoneos4.0
:
软件
将
仅
在
iOS
4.0
或
更高版本
中
运行
,
将
不
能
启动
较早
的
系统
上
。
iphoneos3.1
:
软件
将
运行
在
iOS
4.0
和
iOS
3.1
,
但
将
无法
在
早期
的
系统
上
启动
。
当
运行
在
iOS
3.1
时
,
软件
会
使用
备用
代码
捕获
图像
。
检查
的
目的 C
属性
可用性
通过
传递
给
instancesRespondToSelector
的
getter
方法
名称
(这
是
属性
名称
相同
)
:。
若要
确定
弱
链接
的
C
函数
是否
可用
,
请
使用
链接器
将
不可用
的
函数
的
地址
设置
为
NULL
的
事实
。
检查
函数的
地址 — —
因此
,
其
可用性 — — 通过
比较
为
NULL
或
零
地址
。
例如
,
在
一个
项目
的
部署
目标
是
早
于
OS
X
v10.5
中
使用
CGColorCreateGenericCMYK
函数
之前
,
使用
类似
如下
的
代码
:
清单
3-2
的
C
函数
的
可用性
检查
if (CGColorCreateGenericCMYK != NULL) { |
CGColorCreateGenericCMYK (0.1,0.5.0.0,1.0,0.1); |
} else { |
// Function is not available. |
// Alternate code to create a color object with earlier technology |
} |
注意
:
为了
床位
一个
函数
,
显式
比较
其
地址
为
NULL
或
零
。
您
不能
使用
否定
运算符
(!)
来
否定
函数
的
地址
,
以
检查
其
可用性
。
另外
,
请注意
C
函数
的
名称
是
其
地址
的
代名词
。
那
就
是
,
& myFunction
等于
myFunction
。
检查
外部
(extern)
常量
或
通知
名称
的
可用性
通过
显式地
将
其
地址 — — 而
不
是
符号的
光秃
的
名称 — — 为
NULL
或
零
。
链接
到
整个
框架
的
弱
如果
你
使用
的
最近
添加
的
框架 — — 一个
后
您
的
部署
目标
成为
可用
— — 你
必须
显式
薄弱
环节
到
框架
本身
。
比如说
,
你
想
要
链接
到
加速
框架
,
第一次
在
iOS
4.0
中
,
使用
其
功能
,
他们
可用
的
系统
上
可用
。
此外
,
说
你
设置
你
的
部署
目标
为
iOS
3.1.3
,
允许
的
那个
版本
的
iOS
用户
使用
您
的
应用程序
不用
新
的
特点
。
在
此
示例
中
,
您
必须
对
加速
框架
的
薄弱
环节
。
使用
可
在
您
的
部署
目标
框架
时
,
你
应该
要求
这
一
框架
(和
不
弱
链接
它)。
如何
弱
链接
到
一个
框架
的
信息
,
请参阅
链接
库
和
框架
Xcode
项目
管理
指南 》
。
有条件地
编译
为
不同
Sdk
如果
你
使用
一
套
源代码
生成
多
个
基地
sdk
,
您
可能
需要
为
基地
SDK
中
使用
conditionalize
。
这样
通过
预处理器
指令
使用
在
Availability.h
中
定义
的
宏
。
注
:
Availability.h
标头
是
针对
iOS
和
针对
OS
X
v10.6
及
更高版本
。
在
OS
X
v10.2
介绍
了
旧
的
AvailabilityMacros.h
头
。
这些
文件
驻留
在
/usr/include
目录
中
。
假设
你
想
要
编译
的
代码
清单
3-2
使用
基地
的
SDK
设置
的
macosx10.4
中
所示
。
指
的是
CGColorCreateGenericCMYK
函数
的
代码
的
部分
— — 介绍
OS
X
v10.5 — — 必须
在
生成
期间
蒙面
。
这
是
因为
任何
不可用
的
CGColorCreateGenericCMYK
函数
的
引用
会
导致
编译器
错误
。
若要
允许
代码
以
生成
,
请
使用
__MAC_OS_X_VERSION_MAX_ALLOWED
宏
:
确保
该
项目的
目标
是
OS
X
和
iOS
不
在
基地
的
SDK
中
不可
用的
隐藏
代码
下面
的
代码
摘录
演示
此
操作
。
请注意
,
数值
1050年
而不是
符号
__MAC_10_5
#if
比较
子句
中
使用
:
如果
在
不
包含
符号
定义
的
旧
系统
上
加载
的
代码
,
比较
仍然
工作
。
清单
3-3
使用
条件
编译
预处理器
指令
#ifdef __MAC_OS_X_VERSION_MAX_ALLOWED |
// code only compiled when targeting OS X and not iOS |
// note use of 1050 instead of __MAC_10_5 |
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 |
if (CGColorCreateGenericCMYK != NULL) { |
CGColorCreateGenericCMYK(0.1,0.5.0.0,1.0,0.1); |
} else { |
#endif |
// code to create a color object with earlier technology |
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 |
} |
#endif |
#endif |
} |
除了
使用
预处理器
宏
,
前面
的
代码
还
假定
代码
可能
会
编译
使用
较新
的
基地
SDK
但
运行
OS
X
v10.4
的
计算机
上
部署
及
更早版本
。
具体来说
,
它
会
检查
弱
链接
CGColorCreateGenericCMYK
符号
之前
试图
调用
它
的
存在
。
这
可以防止
代码
生成
运行时
错误
,
如果
你
建立
针对
较新
的
SDK
代码
,
但
部署
在
较旧
的
系统
上
可能
会出现
。
关于
建立
运行时
检查
,
以
确定
存在
符号
的
详细
信息
,
请参阅
使用
弱
链接
类
iOS
和
使用
弱
链接
方法
和
函数
。
找
出
过时
的
API
使用
实例
随着
iOS
和
OS
X
,
Api
和
它们
包含
的
技术
有时
更改
以
满足
开发人员
的
需要
。
作为
这
种
演变
的
一部分
,
效率
较低
的
接口
是
支持
较新
的
否决
。
可用性
宏
附加
到
在
头
文件
中
声明
帮助
你
找到
弃用
接口
。
参考
文档
也
标志
过时
的
接口
。
注意
:
弃用
并
不
意味着
立即
删除
的
框架
或
库
中
的
接口
。
它
只
是
方式
来
标记
的
接口
存在
更好
的
选择
。
您
可以
在
代码
中
使用
过时
的
Api
。
然而
,
苹果
建议
你
将迁移
到
较新
的
接口
尽快
因为
不建议使用
的
Api
可能
会
删除
从
未来
版本
的
操作系统
。
检查
的
头
文件
或
任何
建议
的
更换
接口
的
信息
过时
API
文档
。
如果
你
编译
与
OS
X
v10.5
部署
目标
的
项目
,
使用
接口
标记
为
已弃用
,
编译器
会
发出
相应
的
警告
。
警告
包含
过时
接口
和
代码
中
使用
的
名称
。
例如
,
如果
HPurge
函数
已
被
弃用
,
那么
你
会
得到
错误
类似
于
以下内容
:
'HPurge'
被
弃用
(
在
/Users/steve/MyProject/main.c:51
声明
)
要
在
您
的
代码
中
查找
过时
的
API
使用
的
实例
,
请
寻找
此
类型
的
警告
。
如果
您
的
项目
具有
很多
警告
,
使用
Xcode
中
的
搜索
字段
来
筛选
基于
"弃用"
关键字
的
警告
列表
。
确定
版本
的
操作系统
或
框架
在
罕见
的
情况下
,
符号
的
运行
的
时间
可用性
检查
不
是
一个
完整
的
解决方案
。
例如
,
如果
方法
的
行为
从
一个
OS
版本
更改
到
另一个
,
或
在
先前
可用
的
方法
修复
bug
,
就
必须
编写
代码
时
,
考虑
这些
变化
。
技术
要
用于
检查
操作系统
版本
取决
于
您
的
目标
平台
,
如下
所示
:
若要
在
运行
时
检查
的
iOS
版本
,
使用
这样
的
代码
:。
NSString * osVersion = [[UIDevice currentDevice] systemVersion];
若要
在
运行
时
检查
版本
的
OS
X
,
请
使用
格式塔
功能
和
系统
版本
选择器
常量
。
另外
,
对于
很多
框架
,
你
可以
在
运行
时
检查
一个
具体
的
框架
的
版本
。
要
做到
这一点
,
使用
全球
框架版本
常数 — — 如果
他们
不
提供
,
由
框架
。
例如
,
应用程序
套件
(
NSApplication.h)
在
声明
NSAppKitVersionNumber
常量
,
你可以使用来检测不同版本的应用程序套件框架:
APPKIT_EXTERN 双 NSAppKitVersionNumber;
#define NSAppKitVersionNumber10_0 577
#define NSAppKitVersionNumber10_1 620
#define NSAppKitVersionNumber10_2 663
#define NSAppKitVersionNumber10_2_3 663.6
#define NSAppKitVersionNumber10_3 743
#define NSAppKitVersionNumber10_3_2 743.14
#define NSAppKitVersionNumber10_3_3 743.2
#define NSAppKitVersionNumber10_3_5 743.24
#define NSAppKitVersionNumber10_3_7 743.33
#define NSAppKitVersionNumber10_3_9 743.36
#define NSAppKitVersionNumber10_4 824
#define NSAppKitVersionNumber10_4_1 824.1
#define NSAppKitVersionNumber10_4_3 824.23
#define NSAppKitVersionNumber10_4_4 824.33
#define NSAppKitVersionNumber10_4_7 824.41
#define NSAppKitVersionNumber10_5 949
#define NSAppKitVersionNumber10_5_2 949.27
#define NSAppKitVersionNumber10_5_3 949.33
你
可以
比较
此
常数的
值
,
以
确定
哪个
版本
的
应用程序
套件
针对
运行
代码
。
一个
典型
的
方法
是
地板
全局
常量
的
值
,
并
检查
结果
反对
在
NSApplication.h
中
声明
的
常数
。
例如
:
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_0) { |
/* On a 10.0.x or earlier system */ |
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) { |
/* On a 10.1 - 10.1.x system */ |
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_2) { |
/* On a 10.2 - 10.2.x system */ |
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_3) { |
/* On 10.3 - 10.3.x system */ |
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_4) { |
/* On a 10.4 - 10.4.x system */ |
} else if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_5) { |
/* On a 10.5 - 10.5.x system */ |
} else { |
/* 10.6 or later system */ |
} |
同样
,
Foundation
(
NSObjCRuntime.h)
在
声明
每个
版本
的
NSFoundationVersionNumber
全球
不断
和
特定
值
。
某些
个别
标头
为
其他
对象
和
组件
也
可
声明
的
版本号
为
NSAppKitVersionNumber
一些
bug
修复
或
功能
是
在
一个
给定
的
更新
可用
。