Xcode指令向编译器发出命令,编译器可以检测正在为其构建的平台和固件。这使你可以定制应用程序,以便安全地利用平台或固件特有的特性。将#if语句添加到代码中,可以根据选项阻塞或公布一些功能。例如,为了检测代码是针对模拟器还是针对iPhone编译的,可以使用目标定义:TARGET_IPHONE_SIMULATOR和TARGET_OS_IPHONE。
简单的OS 3 或后续版本检查让你可以构建特定于OS的块。例如,你可能想在这些块中包含特定于3.0 MapKit的代码,使程序仍可以编译,并且能在2.2.x设备上运行。这种方法使你可以创建特定于版本的构建。如果将来设备条件改变,程序将不能适应。和平台指令一样,这是专用于编译时的检查。
另一种方法是检查运行应用程序所需的最低OS版本。对于本例来说,可以使用任何OS预设。这确保3.0代码完全适用于为3.0及更高版本编译的应用程序。
OS版本的值使用以下基命名模式,3.1以后很可能仍将延续该模式。这些定义摘自一组全球iPhone定义。接下来的小节将展示如何获得这些定义。
2.12.1 获得特定于iPhone的定义
虽然特定于指令的定义不是什么秘密,但是真正了解它们的人并不多。要查看当前特定于iPhone的定义的列表,须执行以下步骤。这些步骤在编译期间转储来自Xcode的一个列表,该列表可用作参考。
(1) 打开本章前面介绍的Hello World iPhone项目的Target Info 窗口。
(2) 在Build选项卡中将以下标志添加到OTHER_CFLAGS:
(3) 构建你的项目。编译时会出现一些错误,但不必理会。
(4) 打开一个Terminal shell,导航到项目文件夹。在其中你会发现一个新文件:main.mi。
(5) 发出以下命令:grep -i iPhone main.mi | open -f。该命令搜索main.mi,找到所有iPhone参考,并将它们添加到一个新的TextEdit文档中。该列表包含所有当前定义的宏元素。将该列表保存到便于访问的地方。
(6) 从项目中去除自定义标志,然后保存项目。现在应该能够顺利地重新构建,不会再有错误。
说明 你的代码还应该解决特定于平台的限制,例如对内置摄像头或麦克风的访问。第14章会更详细地介绍如何围绕这些潜在的障碍编写代码。
2.12.2 运行时检查
编译器指令使你可以构建应用程序特定于2.x和3.x的版本。但是,它们并没有为运行适应当前固件的代码提供途径。
要想将应用程序出售给尽可能多的客户,就应该针对潜在客户使用的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-19 使用记忆标记组织方法和函数列表
要创建新的书签,只需将一个简单的记忆标记定义添加到代码中。例如,要得到图2-20中的第一个分组,可以添加:
还可以使用特殊的记忆标记调用添加分隔线。不要在连字符后面添加任何文本,否则Xcode将添加一个常规书签,而不是分隔线。
书签本身不具有功能,因而不会影响代码。它们只是组织工具,你可以选择使用它们,也可以选择不使用它们。
2.12.4 折叠方法
当需要一次查看代码中的多个部分时,可使用Xcode关闭和打开方法组。将鼠标移动到任何方法左边的边栏中。这时出现一对小三角形。单击一个三角形,Xcode将折叠那个方法的代码,如图2-20所示。省略号表明被折叠的方法。再次单击小三角形,Xcode将展开被折叠的代码。
图2-20 Xcode允许折叠各个方法和函数。当屏幕无法同时显示程序中的所有部分时,通过折叠可以方便地查看程序的各个部分