首页 » iOS编程基础:Swift、Xcode和Cocoa入门指南 » iOS编程基础:Swift、Xcode和Cocoa入门指南全文在线阅读

《iOS编程基础:Swift、Xcode和Cocoa入门指南》6.4 目标

关灯直达底部

所谓目标就是规则与设置的集合,这些规则与设置用于指定如何构建产品。在构建时,你所构建的实际上是个目标(可能还会有多个目标)。

在项目导航器顶部选中Empty Window项目,你会在编辑器左侧看到两部分内容(如图6-7所示):项目本身以及目标列表。Empty Window项目有一个目标:应用目标,叫作Empty Window(就像项目本身一样)。应用目标是用于构建和运行应用的目标。其设置会告诉Xcode如何构建应用;其产品就是应用本身。

在某些情况下,你可能会向项目添加更多的目标:

·你想要执行单元测试或界面测试;为了做到这一点,你会添加一个目标。(第9章将会对测试进行更多的介绍。)

·你想要编写一个框架并作为自己的iOS应用的一部分;借助自定义框架,你可以将共同代码重构到一处,可以通过命名空间来重构其私有性细节信息。自定义框架是需要构建的,因此它也是个目标。(本章后面将会对框架进行更多的介绍。)

·你想要编写应用扩展,比如,今日扩展(出现在通知中心的内容),或图片编辑扩展(出现在照片应用上的图片编辑界面)。它们也都是目标。

项目名与目标列表可以通过两种方式呈现(如图6-7所示):一种是作为列显示在编辑器左侧;如果将该列收起以节省空间,那么它还可以作为弹出菜单显示在编辑器左上角。如果在列或弹出菜单中选中了项目,那就可以编辑项目;如果选中了某个目标,那就可以编辑该目标。我会在后面的表述中使用这种说法。

图6-7:展示项目与目标的两种方式

6.4.1 构建阶段

编辑应用目标并单击编辑器顶部的Build Phases(如图6-8所示),这些是应用的构建阶段。构建阶段既描述了目标的构建方式,也包含了一套指令,指示Xcode该如何构建目标;如果修改了构建阶段,那么构建过程也会随之修改。单击每个构建阶段可以查看该构建阶段所应用的目标中的文件列表。

有两个构建阶段是有内容的。这些构建阶段的含义也是一目了然的:

图6-8:应用目标的构建阶段

编译源

会编译某些文件(代码),生成的编译代码会被复制到应用中。

该构建阶段通常会作用于所有目标的.swift文件上;它们是构成目标的代码文件。显然,它会包含ViewController.swift与AppDelegate.swift。如果向项目添加了新的Swift文件(通常是为了声明另一个类),那么你应该将其指定为应用目标的一部分,它会自动添加到编译源构建阶段中。

复制包资源

某些文件会被复制到应用中,这样在应用运行时,代码或系统就能找到它们了。

该构建阶段目前会作用于资源目录上;添加到资源目录中的任何资源都会被复制到应用中作为目录的一部分。它还会列出启动storyboard文件LaunchScreen.storyboard与应用的界面storyboard文件Main.storyboard文件。

复制并不意味着进行完全的复制。某些类型的文件在复制到应用包中时会通过几种方式被特殊对待。比如,复制资源目录意味着目录中的图标会被写到应用包的顶层,资源目录本身会被转换为.car文件;复制.storyboard文件意味着它会被转换为.storyboardc文件,该文件本身是个包含nib文件的包。

你可以手工修改这些列表,有时也需要这么做。比如,如果项目中的某些文件(如声音文件)不在复制包资源中,但你又想在构建过程中将其复制到应用中,那么你可以将其从项目导航器中拖曳到复制包资源列表中,或(更加简单的方式)单击复制包资源列表下方的“+”按钮来弹出一个对话框,该对话框会列出项目中的所有内容。相反,如果项目中的某些文件位于复制包资源中,但你又不想将其复制到应用中,那么你可以从列表中将其删除;这么做并不会将其从项目、项目导航器或Finder中删除,而只会从复制到应用中的条目列表中删除。

有时需要修改Link Binary With Libraries构建阶段,某些库(通常是框架)会链接到编译后的代码上(编译之后叫作库),这会告诉代码,当应用运行时,设备上需要这些库。Empty Window项目会链接到一些框架,不过它并未使用该构建阶段;相反,它将框架导入为模块,框架就会自动链接。不过,在某些情况下,你需要显式将二进制文件链接到额外的框架上;本章后面将会对此进行介绍。

一个实用的技巧是添加Run Script构建阶段,它会在构建过程中运行一个自定义shell脚本。要想做到这一点,请选择Editor→Add Build Phase→Add Run Script Build Phase。打开新添加的Run Script构建阶段可以编辑自定义shell脚本。最简单的一个shell脚本如下所示:


echo /"Running the Run Script build phase/"  

勾上“Show environment variables in build log”复选框会在Run Script构建阶段的构建报告中列出构建过程中的环境变量及其值。单凭这一点我们就应该加上Run Script构建阶段;通过查看环境变量可以了解到关于构建过程如何进行的很多信息。

6.4.2 构建设置

构建阶段只是目标了解如何构建项目的一个方面。另外一个方面就是构建设置。要想查看构建设置,请编辑目标并在编辑器顶部单击构建设置(如图6-9所示)。你会看到一个长长的设置列表,其中大部分设置都不用修改。Xcode会检查该列表以便了解在构建过程的各个阶段应该做什么。项目之所以会按照期望的方式编译和构建,完全是因为构建设置在起作用。

图6-9:目标构建设置

你可以通过单击Basic或All来显示不同的构建设置。设置会被组合为类别,你可以关闭或打开每个类别标题以节省空间。如果了解想要查看的某个设置,如它的名字,那么你就可以通过右上角的搜索框来过滤显示的设置。

你可以通过单击Combined或Levels来决定构建设置的显示方式;在图6-9中,我单击了Levels,目的是介绍何谓Levels。不仅目标包含了构建设置的值,项目也包含了相同构建设置的值;此外,Xcode拥有一些内建的默认构建设置值。Levels会同时显示出这些层级,这样你就能清楚每个构建设置的实际值的来源了。

要想理解这张图,请从右向左看。比如,Build Active Architecture Only设置的Debug配置(最右侧)默认为No。不过,项目中将其设为了Yes(右侧第2列)。目标并未修改该设置(右边第3列),因此结果就是设置被解析为了Yes(右侧第4列)。

如果想要改变其值,你可以现在就改。你可以在项目层次或目标层次上修改其值。我并不建议你这么做;事实上,你很少会直接操纵构建设置,因为通常情况下,默认值就可以了。然而,你还是可以修改构建设置值的,就在这里修改。要想了解各种构建设置的详细信息,请参考Apple的文档,特别是Xcode构建设置参考文档。此外,你还可以选择某个构建设置,然后在辅助窗格中显示快速帮助以了解更多信息。要想了解各种构建设置的详细信息,请参考Apple的文档,特别是Xcode构建设置参考文档。

6.4.3 配置

实际上,构建设置值会有多个列表,但在执行构建时只有一个列表会发挥作用。每个列表都叫作一个配置。我们需要多个配置,因为你会在不同的时间针对不同的目的采用不同的构建方式,这样就需要某些构建设置在不同的情况下接受不同的值。

默认情况下,有如下两个配置:

调试

该配置用于开发过程,也就是编写和运行应用的时候。

发布

该配置用于后期的测试,也就是在设备上检查性能,以及将应用打包提交到App Store的时候。

之所以需要配置完全是因为项目的需要。要想查看项目中的配置,请编辑项目并单击编辑器顶部的Info(如图6-10所示)。注意到这些配置仅仅是名字而已。你可以添加更多的配置,这只不过是向名字列表中添加名字而已。配置的重要性只在这些名字与构建设置值关联起来时才会显现出来。配置会在项目与目标级别上影响构建设置值。

图6-10:配置

比如,回到目标构建设置(如图6-9所示)并在搜索框中输入“Optim”。你会看到Optimization Level构建设置(如图6-11所示)。Optimization Level的调试配置值是None:在开发应用时,你会使用调试配置来构建,这样代码就会以一种直观的方式一行一行地进行编译。Optimization Level的发布配置值是Fast;当应用准备发布时,你会使用发布配置进行构建,这样生成二进制文件时就会针对速度进行优化,非常适合于用户在设备上运行应用,但却不适合开发,因为调试器中的断点与步进将无法使用。

图6-11:配置是如何影响构建设置的

对于发布配置Optimization Level设置,更好的选择是Fast,Whole Module Optimization。这样,Swift编译器就会立刻检查所有代码文件。编译时间可能会长一些,不过优化结果会更好;比如,编译器可能会推断出某些类成员无须动态分派,这会加快代码的运行速度。

6.4.4 方案与目标

到目前为止,我还没有介绍在某次构建过程中,Xcode是如何知道配置的。这是由方案来决定的。

方案会根据构建目的将一个或多个目标与构建配置组合起来。在默认情况下,新的项目都自带一个方案,并以项目名命名。这样,Empty Window项目的方案就叫作Empty Window。要想查看它,请选择Product→Scheme→Edit Scheme,这会打开模式编辑器对话框(如图6-12所示)。

图6-12:方案编辑器

方案编辑器左边列出的是你可以从Product菜单中执行的各种动作。单击某个动作可以在该方案中查看到其相应的设置。

第1个动作构建动作与其他动作不同,因为其他动作都会用到构建动作,其他动作都会隐式涉及构建。构建动作只是在其他动作执行时用来决定构建哪些目标。对于我们的项目来说,它意味着无论执行的动作是什么,应用目标总是会被构建。

第2个动作(运行动作)决定了构建和运行时所需的设置。构建配置弹出菜单(在信息窗格中)被设为了调试。这说明了当前的构建配置的来源:现在,在构建和运行时(Product→Run,或单击工具栏中的Run按钮),你使用的是调试构建配置和与其相对应的构建设置值,因为你使用的是该方案,这正是构建与运行时该方案所要做的事情。

你可以编辑已有的方案,不过一般来说不需要这么做。另一种可能是创建新的方案。一种方式是从项目窗口工具栏的Scheme弹出菜单中选择Manage Schemes(如图6-13所示)。

方案弹出菜单是经常会用到的一个功能。所有方案都会在此列出,因此在构建和运行前可以轻松在各个方案间切换。目标(Destination)会以层次方式附加到每个方案上。目标就是运行应用的机器。比如,你可能会在物理设备或模拟器中运行应用。如果是模拟器,那就需要指定要模拟的特定类型的设备。可以在方案弹出菜单中选择目标。

图6-13:方案弹出菜单

目标与方案之间并没有什么关系。方案弹出菜单中会有目标主要是起到方便的作用,这样你就可以使用弹出菜单一次性地来选择方案或目标了,也可以同时选择这两者。要想在不改变方案的情况下切换目标,请在方案弹出菜单中单击目标名。要想切换方案,或确定目标(如图6-13所示),请在方案弹出菜单中单击方案名。

每个模拟设备都有一个安装到设备上的系统版本。目前,我们所模拟的设备都运行着iOS 9.0;这样就没有差别了,系统版本就没有显示出来。不过,可以在Xcode的首选项窗格中下载其他SDK(系统)。如果下载了并且应用可以运行在多个系统版本上,你还会在Scheme弹出菜单中看到系统版本成为目标名的一部分。比如,如果安装了iOS 8.4 SDK,同时项目的部署目标(参见第9章)是8.0,那么项目窗口工具栏中的方案弹出菜单就会在目标名后面显示“iOS 9.0”或是“iOS 8.4”。

如果下载了额外的SDK,并且应用配置为在多个系统上运行,要是看不到使用了这些系统的任何模拟设备,那么请选择Window→Device来弹出Devices窗口。这是管理模拟设备的地方。可以在这里创建、删除和重命名模拟设备,还可以指定某个模拟设备是否会作为目标出现在方案弹出菜单中。