Xcode指令向编译器发出命令,编译器可以检测正在为其构建的平台和固件。这使你可以定制应用程序,以便安全地利用平台或固件特有的特性。将#if语句添加到代码中,可以根据选项阻塞或公布一些功能。例如,为了检测代码是针对模拟器还是针对iPhone编译的,可以使用目标定义:TARGET_IPHONE_SIMULATOR和TARGET_OS_IPHONE。
另一种方法是检查运行应用程序所需的最低OS版本。对于本例来说,可以使用任何OS预设。这确保3.0代码完全适用于为3.0及更高版本编译的应用程序。
OS版本的值使用以下基命名模式,3.1以后很可能仍将延续该模式。这些定义摘自一组全球iPhone定义。接下来的小节将展示如何获得这些定义。
2.12.1 获得特定于iPhone的定义
(1) 打开本章前面介绍的Hello World iPhone项目的Target Info 窗口。
(2) 在Build选项卡中将以下标志添加到OTHER_CFLAGS:
(3) 构建你的项目。编译时会出现一些错误,但不必理会。
(6) 从项目中去除自定义标志,然后保存项目。现在应该能够顺利地重新构建,不会再有错误。
说明 你的代码还应该解决特定于平台的限制,例如对内置摄像头或麦克风的访问。第14章会更详细地介绍如何围绕这些潜在的障碍编写代码。
2.12.2 运行时检查
要想将应用程序出售给尽可能多的客户,就应该针对潜在客户使用的SDK的最低版本进行构建。如果iPod客户在犹豫是否付费升级到更新的固件,你仍可以出售使用较旧固件规范的软件,只要它经过了严格的测试,能在更新的固件上运行就可以了。
但是,如果你想使用更新的类和调用,那么,你要么会失去使用较旧固件的客户,要么需要开发提供那些特性,同时针对较早固件进行编译的应用程序。这意味着要在运行时而不是编译时检查兼容性。
实现方式有很多种。首先,可以调用固件适用性方法,检查设备上运行的系统。下面的示例代码正是这么做的。对于2.x构建,它会产生编译时警告,让你知道表格单元可能不会响应textLabel。但是,一般不推荐使用这种方法。苹果公司建议检查功能性和可用性,而不是检查特定的固件版本。
还可以测试对象,看它们是否能响应特定的选择器。当框架的3.x版本可用时,对象将报告它们响应那些选择器,允许你调用它们而不会导致程序崩溃。和前一种方法一样,这种方法也是生成关于未实现选择器的编译时警告。
要想避免那些编译时警告,可以将特定于3.x的接口声明添加到2.x源代码中。
但是,更好的方法是为项目设置Base SDK和Deployment target。在Target Info→Build Settings中,将Base SDK设为想要面向的OS的最高版本,即某个3.x版本。将iPhone OS Deployment Target设为想要针对其进行构建的最低OS版本。
另外,也可以使用各种其他变通方法,例如间接地抽出标签。以下代码检索标签并设置它的文本。
使用NSClassFromString(),可以从2.x构建访问3.x类。先测试一下,看看这个类是否返回空值。如果不是,就可以在当前固件中使用这个类。你应该链接可能使用的任何框架,无论它是否可用于2.x构建。
如果真的想深入研究一下,可以直接构建NSInvocation实例,第3章将对此进行讨论。
2.12.3 记忆标记
将书签添加到每个Xcode窗口顶端的方法列表弹出按钮中,可以利用pragma mark(记忆标记)组织源代码。该列表显示当前文档中的所有可用方法和函数。通过添加记忆标记,可以将相关的项编为一组,如图2-19所示。通过在下拉列表中单击这些标签,可以跳转到文件中的某个区域(例如,跳至tag utilities)以及特定的方法(如-tagExists:)。
要创建新的书签,只需将一个简单的记忆标记定义添加到代码中。例如,要得到图2-20中的第一个分组,可以添加:
还可以使用特殊的记忆标记调用添加分隔线。不要在连字符后面添加任何文本,否则Xcode将添加一个常规书签,而不是分隔线。
书签本身不具有功能,因而不会影响代码。它们只是组织工具,你可以选择使用它们,也可以选择不使用它们。