了解您的应用程序的核心对象
UIKit 框架为所有应用程序提供基础结构,但仍然需要您自定对象来赋予应用程序的具体行为。您的应用程序,由一些特定的 UIKit 对象组成,这些 UIKit 对象管理事件循环以及与 iOS 的主要交互。通过组合运用子类化、委托和其他技巧,您可以修改 UIKit 所定义的默认行为,来实现您的应用程序。
除了自定 UIKit 对象以外,您还需要负责提供或定义其他多组关键的对象。最大的一组对象,是应用程序的数据对象,它们的定义,完全由您负责。您还必须提供一套用户界面对象。幸运的是,UIKit 提供了许多类,让您轻松地定义界面。除编程以外,您还必须提供资源和数据文件,这些文件是交付可发行应用程序所需要的。
《iOS App Programming Guide》(iOS 应用程序编程指南)详细描述了此文章中提及的许多主题。
应用程序的核心对象
从用户启动您的应用程序直到退出,UIKit 框架管理着应用程序的许多核心行为。应用程序的心脏,是 UIApplication
对象,它从系统接收事件,然后将事件分派到您的自定代码进行处理。其他 UIKit 类也参与应用程序行为的部分管理,所有这些类都使用相似的方式,调用您的自定代码来处理细节。
要理解 UIKit 对象如何配合您的自定代码来工作,需要理解一下组成 iOS 应用程序的对象。图 1 显示 iOS 应用程序中最常见的对象,表 1 描述每个对象的角色。从框图中,您可以看到,iOS 应用程序是围绕“模型-视图-控制器”设计模式来组织的。此模式将模型中的数据对象,从用来显示该数据的视图中分离出来。这种分离使得随着需要来交换视图成为可能,从而提高了代码重用性,这在创建通用应用程序时特别有用(即可以同时在 iPad 和 iPhone 上运行的应用程序)。
对象 | 说明 |
---|---|
| 您基本上按原样使用 |
应用程序委托对象 | 应用程序委托是在应用程序启动时,创建的一个自定对象,通常由 在 iOS 5 和更高版本中,您可以使用应用程序委托,来处理其他与应用程序相关的事件。Xcode 项目模板将应用程序委托声明为 |
文稿和数据模型对象 | 数据模型对象储存应用程序的内容,是您的应用程序专有的。例如,银行业务应用程序,可能储存包含金融交易的数据库;而绘图应用程序,则可能储存图像对象,甚至储存创建该图像的绘图命令序列。(就绘图命令来说,图像对象仍是一个数据对象,因为它只是图像数据的容器。) 应用程序还可以使用文稿对象(UIDocument 的自定子类),来管理其数据模型对象中的一部分或全部。文稿对象不是必需的,但它们提供了一种便利的方式,对属于单个文件或文件包中的数据进行分组。有关文稿的更多信息,请参阅“定义基于文稿的数据模型”。 |
视图控制器对象 | 视图控制器对象管理应用程序内容在屏幕上的呈现。视图控制器管理单个视图及其分视图。呈现时,视图控制器将视图安装到应用程序的窗口中,使它们显示出来。
|
|
要更改您的应用程序的内容,需使用视图控制器,来更改在对应窗口中显示的视图。您不会把窗口本身替换。 除了充当视图的宿主以外,窗口还配合 |
视图、控制和层对象 | 视图和控制将应用程序的内容直观地呈现出来。视图是一种对象,将内容绘制在指定的矩形区域内,并响应该区域的事件。控制是一类专门的视图,负责实施常见的界面对象,如按钮、文本栏和切换开关。 UIKit 框架提供标准的视图,用于呈现许多类型的内容。通过直接将 除了包括视图和控制以外,应用程序还可以将 Core Animation 层并入其视图和控制分层结构中。层对象实际是代表视觉内容的数据对象。视图在幕后大量使用层对象,来渲染其内容。您还可以将自定的层对象,添加到界面,以实施复杂的动画和其他类型的复杂视觉效果。 |
iOS 应用程序之间的区别,在于所管理的数据(和相应的业务逻辑),以及如何将数据呈现给用户。大多数与 UIKit 对象的交互,并不是替您定义应用程序,而是让它的行为纳入规范。例如,您的应用程序委托的方法,让您知道应用程序的状态何时改变,以便您的自定代码可以适当地作出响应。
数据模型
应用程序的数据模型,由数据结构以及业务逻辑组成,业务逻辑是让数据保持一致状态所必要的。不要把数据模型的设计,脱离应用程序的用户界面来进行;但是,数据模型对象的实现,应该是分开的,而不依赖于特定视图或视图控制器存在与否。保持数据与用户界面分开,有助于实现通用应用程序(可在 iPad 和 iPhone 双平台上运行的应用程序),也让重复使用部分代码变得容易。
如果您尚未定义数据模型,iOS 框架会就这方面为您提供帮助。以下部分重点描述了一些技术,让您使用定义特定类型的数据模型。
定义自定数据模型
定义自定数据模型时,请创建自定对象,来表示任何高级结构。但对简单的数据类型,大可利用系统提供的对象。Foundation 框架提供了许多对象(大部分对象已在表 2 中列出),以面向对象的方式管理字符串、数字以及其他类型的简单数据。使用这些对象,比定义新的对象要好,因为节省时间,而且许多系统例程要求使用内建的对象。
数据 | 类 | 说明 |
---|---|---|
字符串和文本 |
| iOS 中的字符串是基于 Unicode 的。字符串类提供了支持,可以用多种方式创建和操控字符串。带属性的字符串类,支持样式化的文本,须配合 Core Text 使用。 |
数字 |
| 当您要把数值储存在集 (collection) 中时,请使用数字对象。 |
原始字节 |
| 每当需要储存原始字节流时,请使用数据对象。数据对象也常用来以归档形式储存对象。 |
日期和时间 |
| 使用日期对象来储存时间戳、日历日期,以及其他时间相关的信息。 |
URL |
| 除了指向网络资源这一传统用途以外,iOS 中的 URL 还是储存文件路径的首选方式。 |
集 |
| 使用集将相关的对象聚合在一个地方。Foundation 框架提供了几种不同类型的集类。 |
除了与数据相关的对象以外,还有一些其他的数据类型,通常由 iOS 框架用来管理常见类型的数据。鼓励您在自定的对象中使用这些数据类型,来表示相似类型的数据。
NSInteger
/NSUInteger
——有符号的标量和无符号的整数的抽象,基于架构定义了整数的大小。NSRange
——一种结构,用来定义一个序列的连续部分。例如,您可以使用范围定义字符串中被选定的字符。NSTimeInterval
——给定时间间隔中的秒数(整数和小数)。CGPoint
——x 和 y 坐标值,定义一个位置。CGSize
——坐标值,定义一组水平和垂直的范围。CGRect
——坐标值,定义一个矩形的区域。
当然,在定义自定对象时,您总是可以将标量值直接并入到类的实现中。实际上,自定数据对象的成员变量,可以混用标量和对象类型。列表 1 是一个类定义的示例,用于一组图片的集。此示例中的类,包含一个图像数组,以及在这个数组中代表所选项目的索引列表。该类还包含集标题名称的字符串,以及一个标量 Boolean 变量,指示当前的集是否可编辑。
列表 1 自定数据对象的定义
@interface PictureCollection :NSObject |
@property (nonatomic, copy) NSString * title; |
@property (nonatomic) BOOL editable; |
@property (nonatomic, readonly) NSOrderedSet* pictures; |
@property (nonatomic) NSMutableIndexSet *selection; |
// Method definitions... |
@end |
要考虑自定对象上的撤销操作如何处理。支持撤销,意味着能够干净利落地复原对您的对象所做的更改。如果您的对象包含复杂的业务逻辑,就需要将此逻辑分解,赋予容易撤销的方式。以下是在自定对象中实现撤销支持的一些技巧:
定义您需要的方法,以确定对您的对象的修改是对称的。例如,如果您定义了一个方法来添加项目,请确定也有一个方法,用相似的方式来移除项目。
把您的业务逻辑,从您用来修改成员变量值的代码中分解出来。
对于多步骤操作,请使用现有的
NSUndoManager
对象,将步骤组合起来。
使用 Core Data 定义结构化数据模型
Core Data 是一种模式驱动的 (schema-driven) 对象图管理和持久性框架。从根本上讲,Core Data 帮助您将模型对象(以“模型-视图-控制器”设计模式的方式)存储到一个文件中,然后再将它们取回来。这类似于归档,但 Core Data 远不止那些。
Core Data 提供了一个基础结构,来管理对模型对象所做的修改。它让您自动支持撤销和重做,以及维持对象之间的相互关系。
它允许您在任何给定的时间内,仅将模型对象的子集保存在内存中,这对于 iOS 应用程序是非常重要的。
它使用模式来描述模型对象。在基于 GUI 的编辑器中,您定义模型类的主要功能(包括模型类之间的关系)。模式“免费”提供了丰富的基本功能,包括设定默认值和验证属性值。
它允许您维护编辑对象的不相交集合。不相交集合很实用,例如,您想要允许用户在一个视图中进行可被放弃的编辑,而不影响另一个视图中显示的数据。
它具有的基础结构,用于数据储存版本管理和迁移。版本管理可让您轻松地将旧版本的用户文件升级到当前版本。
它允许您在 iCloud 中储存数据,然后从多个设备访问数据。
定义基于文稿的数据模型
基于文稿的数据模型,可以便捷地用于管理被应用程序写入磁盘的文件。这种类型的数据模型,让您使用文稿对象来表示磁盘上单个文件(或文件包)的内容。该文稿对象负责读写文件的内容,并配合应用程序的视图控制器工作,将文稿的内容显示在屏幕上。文稿对象的传统用途,是管理包含用户数据的文件。例如,创建并管理文本文件的应用程序,会使用单独的文稿对象管理每个文本文件。但是,您可以将文稿对象用于专用的应用程序数据(也通过文件来支持)。
图 2 说明了应用程序的数据模型中的文稿、文件和对象之间的典型关系。在少数例外情况下,每个文稿是自包含的,不直接与其他文稿交互。文稿管理单一的文件(或文件包),并在内存中标识在该文件中找到的任何数据。因为每个文件的内容是唯一的,与每个文稿相关联的数据结构,也是唯一的。
您使用 UIDocument
类来实现 iOS 应用程序中的文稿对象。此类提供基本的基础结构,以处理文稿的文件管理各方面所需。UIDocument
的其他好处包括:
它支持在合适的时间自动存储文稿内容。
它为储存在 iCloud 中的文稿处理所需要的文件协调。它还为解决版本冲突提供了钩子 (hook)。
它为撤销操作提供了支持。
为了实施应用程序的文稿所要求的特定行为,您必须创建 UIDocument
的子类。
用户界面
每个 iOS 应用程序,都至少有一个窗口和一个视图,来显示它的内容。窗口提供了在其中显示内容的区域,是 UIWindow
类的实例。视图负责管理内容的绘制(并处理触摸事件),是 UIView
类的实例。对于使用视图对象构建的界面而言,应用程序的窗口自然包含多个视图对象。对于使用 OpenGL ES 构建的界面而言,通常只有一个视图,并使用该视图来渲染内容。
视图控制器也在应用程序的用户界面中,扮演很重要的角色。视图控制器是 UIViewController
类的实例,负责管理一组视图,以及那些视图与应用程序的其他部分之间的交互。因为 iOS 应用程序显示内容的空间很有限,视图控制器也提供了所需要的基础结构,从一个视图控制器中撤出视图,以另一个视图控制器中的视图来替换。因此,视图控制器是您实施各种类型的内容转换的方式。
您要经常将一个视图控制器对象,作为自包含的单元来看。它处理其自身视图的创建和销毁,处理其视图在屏幕上的显示,并协调视图和应用程序中的其他对象之间的交互。
使用 UIKit 视图构建界面
使用 UIKit 视图进行绘图的应用程序很容易创建,因为您可以快速组装一个基本界面。UIKit 框架提供了许多类型的视图,来帮助呈现和组织数据。控制是一种特殊类型的视图,它提供了一个内建机制,每当用户执行了合适的操作,即执行自定代码。例如,点按按钮,导致与该按钮关联的操作方法被调用。
基于 UIKit 视图的界面的好处是,您可以使用 Interface Builder(内建在 Xcode 中的可视化界面编辑器)以图形方式组装它们。Interface Builder 提供了一个资源库,包含了标准视图、控制,以及构建界面所需要的其他对象。将对象从资源库拖出并放置在工作前台,而且可以根据需要随意进行安放。接着可使用检查器配置对象,然后再将它们存储到串联图或 nib 文件中。以图形方式组装界面的过程,比编写同等代码要快得多,您立即看到结果,而不需要先生成并运行应用程序。
图 3 显示了应用程序的基本结构,其界面仅使用视图对象构建。在此实例中,主视图利用了窗口的可见区域(状态条除外),提供一个简单的白色背景。主视图还包含三个分视图:一个图像视图、一个文本视图和一个按钮。应用程序使用那些分视图,来向用户显示内容并响应交互。层次中的所有视图,都是由一个视图控制器对象来管理。
在典型的基于视图的应用程序中,您使用视图控制器对象来协调屏幕视图。应用程序总是有一个视图控制器,负责在屏幕上显示所有内容。该视图控制器具有一个内容视图,其本身可能包含其他视图。有些视图控制器也可以用作容器,供其他视图控制器提供的内容使用。例如,分离视图控制器会并排显示两个视图控制器的内容。
使用视图和 OpenGL ES 构建界面
游戏以及其他需要很高帧速率或复杂绘图功能的应用程序,可以将专门为 OpenGL ES 绘图而设计的视图添加到其视图层次中。最简单的 OpenGL ES 应用程序类型,具有一个窗口对象、一个视图(用于 OpenGL ES 绘图),以及一个视图控制器,来管理内容的显示和旋转。更复杂的应用程序,可以混用 OpenGL ES 视图和 UIKit 视图,来实施其界面。
图 4 显示了一个应用程序的配置,该程序只使用一个 OpenGL ES 视图来绘制其界面。不像 UIKit 视图,OpenGL ES 视图是由一种不同类型的层对象(CAEAGLLayer
对象)来支持的,而不是基于视图的应用程序所使用的标准层。CAEAGLLayer
对象提供了 OpenGL ES 可以将内容渲染在其中的绘图表面。要管理绘图环境,应用程序也创建 EAGLContext
对象,并将该对象连同视图储存下来,使它容易取回。
应用程序包
当您生成 iOS 应用程序时,Xcode 将它捆绑成一个包。捆绑包 (bundle) 是文件系统中的一个目录,它将相关资源成组在一个地方。一个 iOS 应用程序捆绑包中,含有其可执行文件和支持资源文件(如应用程序图标、图像文件和已本地化的内容)。表 3 列出了一个典型的 iOS 应用程序捆绑包(名为 MyApp
,用于演示目的)的内容。此示例仅用于图解目的。此表中列出的某些文件,可能不会出现在您自己的应用程序捆绑包中。
文件 | 示例 | 说明 |
---|---|---|
应用程序可执行文件 |
| 可执行文件包含应用程序的已编译代码。将应用程序名称去掉 此文件是必需的。 |
信息属性列表文件 |
|
此文件是必需的,而且名称必须为 |
应用程序图标 |
| 应用程序图标用来在设备的主屏幕上表示应用程序。其他图标由系统用在合适的地方。其文件名中含有 应用程序图标是必需的。 |
启动画面 |
| 应用程序启动时,系统将此文件用作临时背景。一旦应用程序准备好显示其用户界面,它就会被移走。 至少需要一个启动画面。 |
串联图文件(或 nib 文件) |
| 串联图含有视图和视图控制器,应用程序通过它们,将内容呈现在屏幕上。串联图中的视图,是根据显示它们的视图控制器来组织的。串联图也确定一组视图的转换(称为过渡),将用户从一组视图带到另一组。 当您创建项目时,主串联图文件的名称由 Xcode 设定。您可以通过给 使用串联图不是硬性规定,但建议您还是使用它。 |
临时分发图标 |
| 如果您准备临时分发应用程序,请准备好一个 512 x 512 像素版本的应用程序图标。此图标正常由 App Store 从您提交到 iTunes Connect 的材料中提供。然而,由于应用程序是临时分发的,没有通过 App Store 审批,您的图标必须存在于捆绑包中。iTunes 使用此图标来表示您的应用程序。(如果您准备用那种方式来分发应用程序,则指定的文件就应该与您已提交到 App Store 的那个文件一样。) 此图标的文件名必须是 |
设置捆绑包 |
| 如果想要通过“设置”应用程序,来展示自定的应用程序偏好设置,您必须准备好一个设置捆绑包 (settings bundle)。此捆绑包含有属性列表数据,还包含定义应用程序偏好设置的其他资源文件。“设置”应用程序使用此捆绑包中的信息,来组装所需要的界面元素。 此捆绑包是可选的。 |
非本地化资源文件 |
| 非本地化资源包括应用程序所使用的图像、声音文件、影片和自定数据文件之类的资源。所有这些文件,都应该放置在应用程序捆绑包的顶层位置。 |
本地化资源的子目录 |
| 本地化资源必须放置在语言特定的项目目录中,目录的名称由 ISO 639-1 语言缩写和 iOS 应用程序应该是国际化的,对于所支持的每一种语言,都有一个语言 |
© 2013 Apple Inc. 保留一切权利。(上次更新:2013 年 4 月 23 日)