第3章 创建你的第一个iPhone应用程序.pdf

上传人:qwe****56 文档编号:74659260 上传时间:2023-02-27 格式:PDF 页数:29 大小:1.12MB
返回 下载 相关 举报
第3章 创建你的第一个iPhone应用程序.pdf_第1页
第1页 / 共29页
第3章 创建你的第一个iPhone应用程序.pdf_第2页
第2页 / 共29页
点击查看更多>>
资源描述

《第3章 创建你的第一个iPhone应用程序.pdf》由会员分享,可在线阅读,更多相关《第3章 创建你的第一个iPhone应用程序.pdf(29页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、 第 3 章 创建你的第一个 iPhone 应用程序 本章将介绍如何创建一个简单的 iPhone 应用程序。本文不打算对 iPhone 目前可用的特性作全面介绍,而是介绍一些基础的技术,但这些基础技术,不要求你现在一定掌握,如果你不明白,可以跳过,继续进行下面的,你只管根据本章的介绍进行“照葫芦画瓢”就可以可以,这样目的是,使你对基础开发过程有初步了解,窥视一下开发 iPhone 程序的神秘色彩,打破对开发 iPhone 程序的那种畏惧感。这也是介绍本章的最重要的目的。注意:为了学习本本章,需要安装 iPhone SDK 和开发者工具,它们位于 iPhone 开发中心。文档描述的工具包含在 i

2、Phone SDK v3.0 里面请检查一下 Xcode 版本,它不能低于 3.1.3。3.1 示例实现目标 在学习过程中,将创建一个很简单的应用程序。它含有一个文本字段,一个标签和一个按键。可以把名字输入到文本字段中,再按下按键,这时标签的文本就会变成“Hello,!”。如图 3-1 所示。图 3-1 程序运行效果 尽管这是个很简单的应用程序,但它介绍了基本的设计模式、工具、以及利用 Cocoa Touch 进行iPhone 开发的基础技术。Cocoa Touch 包括 UIKit 和 Foundation 这两个框架。当在 iPhne OS 上开发事件驱动的图形化应用程序时,需要使用它们提

3、供的工具和基本结构。同时,Cocoa Touch 还包含其他几个框架,它们提供一些基本的服务,可用于访问设备的特色内容,例如访问用户的联系人。3.2 应用概念概述 在介绍创建之前,先初步了解一下在创建中应用的一些基本概念,它们主要有设计模式、委托、模型视图控制器和目标动作等,了解这些概念将有助于理解后面创建机制。这些概念,将是以后在 iPhone/iPad 开发中经常用到的一些应该概念。基于篇幅的限制,这里只简单的介绍一下,如果想更进一步的了解,建议找专门介绍这些方面的书籍。3.2.1 设计模式 设计模式是一种设计模板,用于解决在特定环境中反复出现的一般性的问题。它是一种抽象工具,在架构、工程

4、、和软件开发领域相当有用。下面的部分将概要说明什么是设计模式,解释为什么设计模式在面向对象的设计中非常重要,并讨论一个设计模式的实例。3.2.2 委托 委托模式是一个对象周期性地向被指定为其委托的另一个对象发送消息,向其请求输入或者通知某件事情正在发生。该模式可替换类继承来对可复用对象的功能进行扩展。在本文将要创建的应用程序中,应用程序对象会向其委托发送消息,通知它主要的启动例程已经完成并且定制的配置可开始执行。为了建立并管理视图,委托会创建一个控制器实例。另外,当用户点击Return 按键后,文本字段也会通知它的委托(即所创建的控制器对象)。委托方法通常会集中在一起形成一份协议。一份协议基本

5、上就是一个方法的列表。如果一个类遵循某个协议,则它要保证实现协议所要求的方法(有些方法可选择实现与否)。委托协议规定了一个对象可以发送给委托的所有消息。委托是一种对象,当向外委托任务的对象遇到程序中的事件时,它的委托可以代表它对事件进行处理,或者和它进行协调。向外委托任务的对象通常是一个响应者对象即继承自 NSResponder 的对象负责响应用户事件。委托则是受托进行事件的用户界面控制,或者至少根据应用程序的具体需要对事件进行解释的对象。为了更好地理解委托的价值,让我们考虑一个复活的 Cocoa 对象,比如一个窗口(NSWindow 的实例)或者表视图(NSTableView 的实例)。这些

6、对象的设计目的是以一般的方式实现一个具体的角色;举例来说,窗口对象负责响应窗口控件的鼠标操作,处理象关闭窗口、调整尺寸、以及移动窗口的位置这样的事件;这个受限而又具有一般性的行为必然限制该对象认识一个事件对应用程序其它地方的影响,特别是当被影响的行为只存在于 的应用程序的时候。委托为 的定制对象提供一种方法,使它可以就应用程序特有的行为和复活对象进行通讯。委托的编程机制使对象有机会对自己的外观和状态、以及程序在其它地方发生的变化进行协调,这些变化通常是由用户动作触发的。更重要的是,委托使一个对象有可能在没有进行继承的情况下改变另一个对象的行为。委托几乎总是 的一个定制对象,它通过定义将应用程序

7、具体逻辑结合到程序中,而 这些逻辑是具有一般性的,是向外委托任务的对象自身不可能知道的。委托是如何工作的委托是如何工作的 委托机制的设计是很简单的(图 5-2)。希望向外委托任务的类需要有一个插座变量,通常命名为delegate,并包含对该插座变量进行设置和访问的方法。它还需要声明一或多个方法,构成一个非正式的协议,但不进行实现。非正式协议通常是希望向外委托任务的类的一个范畴,和正式协议的不同之处在于,它不需要实现协议中的所有方法。在非正式协议中,委托只实现希望进行协调或对缺省行为实施影响的方法。图 5-2 委托的机制 非正式协议的方法标记着进行任务委托的对象需要处理或预期发生的重大事件。该对

8、象希望就这些事件和委托进行交流,或者就即将发生的事件向委托请求输入或批准。举例来说,当用户点击一个窗口的关闭按键时,窗口对象会向委托发送 windowShouldClose:消息;这就使委托有机会否决或推迟窗口的关闭,如果必须保存窗口关联数据的话(参见图 5-3)。图 5-3 一个更接近现实的、涉及委托的序列 3.2.3 模型-视图控制器 模型-视图-控制器模式(MVC)是一个相当老的设计模式,它的一些变体至少在 Smarttalk 的早 期就出现了。它是一种高级别的模式,关注的是应用程序的全局架构,并根据各种对象在程序中发挥的作用对其进行分类。它也是个复合的模式,因为它是由几个更加基本的模式

9、组成的。模型对象表示数据。例如,在一款游戏中,SpaceShips 和 Rockets 是模型对象,在一个用于生产的应用中,ToDo 项和 Contacts 是模型对象,在一个绘画应用中,Circles 或 Squares 是模型对象。视图对象知道如何显示数据(模型),并且它们有可能会允许用户对数据进行编辑。在本文将要创建的应用程序中,需要一个主视图来包含其它几个视图 一个文本字段,它用于捕获用户输入信息;第二个文本字段,它用于显示文本,而文本内容则是基于用户的输入;另外还需要一个按键,用户利用它来告知我们第二个文本字段应该被更新。控制器对象位于模型和视图之间。面向对象的程序在设计上采用 MV

10、C 模式会带来几个方面的好处。这种程序中的很多对象可能更具重用性,它们的接口也可能定义得更加良好。程序从总体上更加适应需求的改变换句话说,它们比不基于 MVC 的程序更加容易扩展。而且,Cocoa 中的很多技术和架构比如绑定技术、文档架构、和脚本技术都基于 MVC,而且要求定制对象充当 MVC 定义的某种角色。1.模型对象负责包装数据和基本行为模型对象负责包装数据和基本行为 模型对象代表特别的知识和专业技能,它们负责保有应用程序的数据和定义操作数据的逻辑。一个定义良好的 MVC 应用程序会将所有重要的数据封装在模型对象中。任何代表应用程序留存状态的数据(无论该状态存储在文件中,还是存储在数据库

11、中),一旦载入应用程序,就应该驻留在模型对象中。因为它们代表与特定问题域有关的知识和专业技能,所以有可能被重用。在理想情况下,模型对象不和负责表示与编辑模型数据的用户界面建立显式的连接。举例来说,如果有个代表一个人的模型对象(假定 在编写一个地址本),可能希望存储这个人的生日,则将生日存储在 的 Person 模型对象是比较好的做法。但是,日期格式字符串或其它有关日期如何表示的信息可能存储在别的地方比较好。在实践上,这种分隔并不总是最好的,这里有一定的灵活空间。但一般来说,模型对象不应该关心界面和表示的问题。一个具有合理例外的例子是描画程序,它的模型对象代表要显示的图形。图形对象知道如何描画自

12、身是合理的,因为它们存在的主要原因就是为了定义视觉上的信息。但是即使在这种情况下,图形对象也不应该完全依赖于特定的视图,它们不应该负责描画的具体位置,而应该由希望表示这些图形对象的视图对象发出描画的请求。2.视图对象负责向用户表示信息视图对象负责向用户表示信息 视图对象知道如何显示应用程序的模型数据,而且可能允许用户对其进行编辑。视图对象不应该负责存储它所显示的数据(这当然不是说视图永远不存储它所显示的数据。由于性能上的原因,视图可能对数据进行缓存,或使用类似的技巧)。一个视图对象可能负责显示模型对象的一部分或全部,甚至是很多不同的模型对象。视图对象可能有很多变化。视图对象应该尽可能可重用和可

13、配置,它们可以在不同的应用程序中提供一致的显示。在 Cocoa 中,Application Kit 定义了大量的视图对象,其中很多对象都出现在 Interface Builder 的选盘上。可以通过重用 Application Kit 的视图对象,比如 NSButton 对象,来保证应用程序中的按键和其它 Cocoa 应用程序的按键行为是一样的,从而保证不同的应用程序在外观和行为上具有高度的一致性。视图必须正确地显示模型,因此需要知道模型发生的改变。由于模型对象不应该依赖于特定的视图对象,所以需要有一个一般性的方式来指示模型对象发生了变化。3.控制器对象连接模型和视图控制器对象连接模型和视图

14、控制器对象是应用程序的视图对象和模型对象之间的协调者。通常情况下,它们负责保证视图可以访问其显示的模型,并充当交流的管道,使视图可以了解模型发生的变化。控制器对象也可以为应用程序执行配置和协调的任务,管理其它对象的生命周期。在一个典型的 Cocoa MVC 设计中,当用户通过某个视图对象输入一个值或做出一个选择时,该值或选择会传递给控制器对象。控制器对象可能以应用程序特有的方式对用户输入进行解释,然后或者告诉模型对象如何处理这个输入比如“增加一个新值”或“删除当前记录”,或者使模型对象在其某个属性上反应被改变的值。基于同样的用户输入,一些控制器对象也可以通知相应的视图对象改变其外观或行为的某个

15、部分,比如禁用某个按键。反过来,当一个模型对象发生变化了比如加入一个新的数据源模型对象通常将变化通知控制器对象,由控制器对象要求一或多个视图对象进行相应的更新。控制器对象可能是可重用的,也可能是不可重用的,取决于它们的一般类型。Cocoa 控制器对象的类型部分描述 Cocoa 中不同类型的控制器对象。3.2.4 目标-动作 1.目标目标 目标是动作消息的接收者。一个控件,或者更为常见的是它的单元,以插座变量(参见插座变量部分)的形式保有其动作消息的目标。虽然目标可以是任何实现恰当的动作方法的 Cocoa 对象,但通常是 的定制类的一个实例。2.动作动作 动作是控件发送给目标的消息,或者从目标的

16、角度看,它是目标为了响应动作而实现的方法。控件,或者更为常见的是它的单元,将动作存储为 SEL 类型的实例变量。SEL 是一种 Objective-C 的数据类型,用于指定消息的签名。动作消息必须有一个简单而清楚的签名,消息调用的方法没有返回值,且只有一个类型为 id 的参数。该参数约定的名称为 sender。委托、绑定、和通告机制在处理程序中特定形式的对象间通讯是很有用的。但是,对于大多数可视的通讯形式,它们并不特别合适。一个典型应用程序的用户界面是由一些图形对象组成的,最常见的对象可能就是控件。控件是真实世界或逻辑设备的对等物(比如按键,滑块,检查框等)。和真实世界中的控制接口(比如收音机

17、调谐器)一样,可以用控件来传达 对其所在系统的控制意图在这里,系统是一个应用程序。3.目标目标-动作机制动作机制 用户界面中的控件的作用很简单:它对用户的意图进行解释,并指示其它对象执行相应的请求。当用户对控件进行动作,比如点击控件或按下回车键,硬件设备就会产生一个未经加工的事件。控件接受该事件(在根据 Cocoa 的需要进行恰当的封装之后),并将它翻译为应用程序的具体指令。然而,事件的本身并没有给出很多关于用户意图的信息,它们只是告诉 用户点击了鼠标键,或者按下了一个按键。因此,程序需要某些机制来进行事件和指令的翻译。这个机制就是目标-动作机制。Cocoa 通过目标-动作机制来实现控件和对象

18、的通讯。这个机制使控件和它的单元(可能有多个)可以把向恰当对象发送应用程序具体指令所需要的信息封装起来。接受对象通常是个定制类的实例被称为目标(target)。动作是控件发送给目标的消息(action)。对用户事件感兴趣的对象即目标也就是为用户事件给出意义的对象,这个意义通常在动作的名称中反应出来。目标-动作机制允许一个控件对象(诸如按键或滑动条)向另外一个对象发送一条消息(即动作),以之作为对某个用户事件(例如一个点击事件或者一个敲击事件)的响应。接收到消息的对象则可以对消息进行解释,并将其作为一个特定于应用程序的指令进行处理。3.3 教你如何创建工程 在本节,将要使用 Xcode 创建前面

19、所说的工程,同时还将查明应用程序的启动过程。3.3.1 使用 Xcode 主要利用 Xcode 来创建 iPhone 应用程序,它是苹果的 IDE(集成开发环境)。也可以利用它来创建各种不同类型的工程,包括 Cocoa 以及命令行工具,这些知识,在前面的章节中已经介绍过,本节的重点是如何使用 XCode。(1)启动 Xcode(缺省情况下,Xcode 位于/Developer/Applictions 里面),然后请选择 File New Project,这样就可以创建一个新工程。应该会看到一个新的窗口,如图 5-4 所示。图 5-4 创建新工程 注意:如果 没有看到“Use Core Data

20、 for storage”这一选项,则请 务必 安装 iPhone OS SDK 3.0 版本 应该安装 Xcode3.1.3 或者更高的版本。(2)请选中 Window-Based Application 并点击 Choose 按键。(请不要勾选“Use Core Data for storage”,本例不使用 Core Data 机制。)完成上述步骤后,屏幕会出现一张表格。请在上面选择工程的存储位置。(3)请选择一个合适的位置(例如 可以放在桌面也可以放在一个定制的工程目录),然后为工程添加一个名称HelloWorld再点击保存按键。注意:在后续章节中,我们假定 将工程命名为 HelloW

21、orld,因此应用程序的委托类就叫做 HelloWorldAppDelegate。如果使用其他名称,则应用程序委托类的名称将为YourProjectNameAppDelegate。完成上述步骤后,将看到如下的新工程窗口,如图 5-5 所示。图 5-5 新工程窗口 如果以前未曾用过 Xcode,则请花点时间来研究下该应用。请阅读 Xcode 工作空间指南,它可以帮助 理解工程窗口的组织方式以及如何执行诸如编辑和保存文件这样的基本任务。现在,可以链编并运行程序,这样就能看到模拟器的外观。(4)请选择 Build Build and Go(Run)或者点击工具栏中的 Build and Go 按键。

22、iPhone 模拟器应该会自动启动。当 的应用程序启动后,只看到一个白色屏幕。如希望了解白色的屏幕从何而来,则 需先了解应用程序如何启动。(5)退出模拟器。3.3.2 应用程序引导 创建的模板工程已设置了基本的应用程序环境。它创建一个应用程序对象,将应用程序和窗口服务器连接起来,建立一个运行循环以及其他等等。大部分的工作通过 UIApplicationMain 函数完成,如图5-6。图 5-6 应用程序引导 main.m 文件中的 main 函数会调用 UIApplicationMain 函数:int retVal=UIApplicationMain(argc,argv,nil,nil);该函

23、数将会创建一个 UIApplicaion 类的实例。同时它会搜索应用程序的 Info.plist 属性列表文件。Info.plist 文件是一部字典,它包含诸如应用程序名称、图标这样的信息。它也可以包含应用程序对象应该加载的 nib 文件的名称,该名称由 NSMainNibFile 键指定。Nib 文件含有一份用户接口元素及其他对象的档案 将在后续章节进一步了解 Nib 文件的知识。本工程的 Info.plist 文件具有下面的内容:NSMainNibFile MainWindow 这表明应用程序启动时将会加载 MainWindow nib 文件。如希望查看 nib 文件,请双击工程窗口 Re

24、source group 中的 MainWindow.xib 文件。(虽然该文件的扩展名为“xib”,但是习惯称之为“nib 文件”)。Interface Builder 将会启动并打开该文件,如图5-7。图 5-7 interface Builder Interface Builder 文档包含四个对象:一个 文件拥有者代理对象。实际上,文件拥有者对象是 UIApplication 实例 将在“文件拥有者”一节讨论该对象。一个 第一响应者代理对象。一个 HelloWorldAppDelegate 的实例,它会被设置成应用程序的委托。一个窗口。它被设置为白色背景、启动时可见。应用程序启动时,看

25、到的窗口就 是它。应用程序完成启动后,可以执行附加定制。图 5-8 描述的是一种通用模式,对于这种通用模式,将会在下一节使用它。图 5-8 一种通用模式 应用程序对象在完成启动后会向委托发送 applicationDidFinishLaunching:消息。通常情况下,委托不是自己配置用户接口,而是创建一个视图控制器对象(一种特定的控制器,它负责管理一个视图遵循“模型-视图-控制器”描述的模型-视图-控制器设计模式)。然后委托向视图控制器请求视图(这个视图由视图控制器根据要求创建),并将其添加成窗口的子视图。3.4 如何添加一个视图控制器 在本章的示例程序中,需要使用两个类。一个是 Xcode

26、 的应用程序模板提供的应用程序委托,程序在 nib 文件中创建了一个该类的实例。另一个是需要您实现视图控制器类,将创建该类的一个实例。3.4.1 添加一个视图控制器类 在大部分 iPhone 应用程序中,视图控制器起着核心作用。正如其名称所示,它负责管理一个视图。在 iPhone 上,它们也帮助进行导航和内存管理。虽然本节例子程序不使用后两种功能,但对此有所了解很重要。UIKit 提供一个特别的类 即 UIViewController 类它封装了视图控制器应该具有的大部分缺省行为。应从它派生子类,在子类中定制应用程序的行为。(1)请选中 Xcode 项目管理器里的工程(即 HelloWorld

27、 项目,位于 Groups and Files 列表的顶部)或者选中 Classes 文件夹 新文件会被加入到当前选择的位置。(2)请选择 File New File。在 New File 窗口中,请选择 Cocoa Touch Classes,然后选择UIViewController subclass,如图 5-9。同时,请勾选 Options 区域中标题为 With XIB for user interface 的选择框。图 5-9 创建新文件 注意:如果 没有看到“With XIB for user interface”选项,请确保 安装 iPhone OS SDK 3.0 版本-应该安

28、装 Xcode3.1.3 或者更高的版本。选中“With XIB for user interface”表明 Xcode 在创建视图控制器的同时,会为其创建一份 nib 文件,并将该文件添加到工程。(将在下一章详细讨论 Nib 文件。)(3)请点击 Next,在其后出现的屏幕中为文件起个名字,例如 MyViewController。(类名称习惯以一个大写字母开头)。请务必创建.m 和.h 文件,并将二者都添加到工程,如图 5-10 所示。图 5-10 MyViewController (4)请点击 Finish,文件会被添加到工程。看一下新建的源文件,会发现 Xcode 已经为 提供了各种方法

29、的存根实现。目前无需追究这些方法的具体含义。接下来,我们将创建一个控制器类的实例。3.4.2 添加一个视图控制器属性 需确保在应用程序生存期间,视图控制器始终存在。将视图控制器作为应用程序委托的一个实例变量是解决该问题的一个明智的方法。添加到应用程序委托的实例变量是 MyViewController 类的实例。如果 声明了变量但未告知编译器MyViewController 类的相关信息,编译器就会报告错误。通过导入头文件可以解决该问题,但在 Cocoa中,通常 应该使用一个前向声明(forward declaration)它向编译器承诺 MyViewController 类将在其他地方定义,因

30、此编译器现在无需耗时来对其执行检查。(如两个类需相互引用,则前向声明可以避免环状包含,即两个头文件互相包含。)然后,请将 MyViewController 类的头文件导入到应用程序委托的实现文件。(1)请在应用程序委托头文件(HelloWorldAppDelegate.h)的接口声明前面-即HelloWorldAppDelegate 声明前面-添加前向声明:class MyViewController;(2)请在头文件大括号之间添加下面的代码,这是为了向应用程序委托添加一个实例变量:MyViewController*myViewController;(3)请在大括号之后 end 之前添加下面的

31、属性声明:property(nonatomic,retain)MyViewController*myViewController;基本上,上述声明指定:HelloWorldAppDelegate 实例含有一个属性,可以使用 getter 和 setter 方法即 myViewController 和 setMyViewController:方法来访问该属性,同时,委托实例还会保持该属性(将在后续章节详细讨论保持)。为确保正确,请确认 HelloWorldAppDelegate 类的接口文件(即 HelloWorldAppDelegate.h 文件)如下所示(不显示注释):#import cla

32、ss MyViewController;interface HelloWorldAppDelegate:NSObject UIWindow*window;MyViewController*myViewController;property(nonatomic,retain)IBOutlet UIWindow*window;property(nonatomic,retain)MyViewController*myViewController;end 现在 可以开始创建视图控制器的实例。3.4.3 创建视图控制器实例 已经把视图控制器属性添加到应用程序的委托,现在需要实际创建一个视图控制器实例,并

33、将其设置为属性的值。请在应用程序委托类实现文件(即 HelloWorldAppDelegate.m 文件)中的applicationDidFinishLaunching:方法开头添加如下代码,这些代码用于创建一个 MyViewController 实例:MyViewController*aViewController=MyViewController alloc initWithNibName:MyViewController bundle:NSBundle mainBundle;self setMyViewController:aViewController;aViewController

34、release;虽然只有三行,但其中含意很多。这些代码作用如下:创建并初始化一个视图控制器类的实例。使用存取方法将新建的视图控制器是设置为 myViewController 实例变量值。记住:未单独声明 setMyViewController:方法,而是隐式将其作为属性声明的一部分。依照内存管理规则释放视图控制器。先使用 alloc 方法创建一个视图控制器,然后用 initWithNibName:bundle:方法对其进行初始化。init方法先指定控制器应加载的 nib 文件,然后指定在哪个程序包中可找到该文件。程序包是文件系统某个位置的抽象,该位置存放了应用程序将会用到的代码和资源。相比自行

35、定位文件系统的资源文件,使用程序包有很多优势。它为我们提供了方便而简单的 APIbundle 对象仅通过名称就可以定位某个资源甚至连名称的本地化的工作,它也为 考虑了。本章约定应该拥有任何通过本章约定应该拥有任何通过 alloc 方法创建的对象(请参考内存管理规则方法创建的对象(请参考内存管理规则了解其他约定了解其他约定)。因此,还需要:放弃对所创建的对象的拥有权。通常只在初始化函数中调用存取方法来设置实例变量。上述代码第二行使用存取方法来设置实例变量,第三行调用 release 方法以放弃对所创建对象的拥有权。也可以使用其他方式来完成这些功能。例如,可以把这三行代码替换成下面两行:MyVie

36、wController*aViewController=MyViewController alloc initWithNibName:MyViewController bundle:NSBundle mainBundle autorelease;self setMyViewController:aViewController;该版本使用 autorelease 来放弃对新建视图控制器的所有权。不过此种方式中,放弃所有权的动作将在未来的某一时刻执行。如果不理解此代码的含义,则请阅读 Cocoa 内存管理变成指南中 Autorelease Pools 一章。通常情况下,请尽可能地避免使用 auto

37、release 方法,因为相对于 release 方法来说,它是一种资源密集型操作。也可以将最后一行替换如下:self.myViewController=aViewController;此处点号就是调用存取方法(即 setMyViewController:),这与前述实现调用的方法并无不同。点号确实提供一种更为紧凑的语法特别是在使用嵌套表达式的时候。将几个属性合在一起使用时,点号语法能带来一些附加好处,但到底选择哪种语法,则很大程度上取决于个人的偏好。3.4.4 如何建立视图 视图控制器负责管理和配置视图。并不直接创建窗口的内容视图,而是从视图控制器获取,并将其添加成窗口子视图。释放视图控制器

38、后,请添加如下的代码:UIView*controllersView=myViewController view;window addSubview:controllersView;也可以使用一行代码来完成上面代码的功能:window addSubview:myViewController view;但是将代码分为两行有助于强调内存管理的一个规则,它和我们之前看到的相反。由于并未使用Cocoa 内存管理编程指南中的内存管理规则里所列出的方法来创建控制器视图,所以并不拥有该视图。因此,把返回的对象传给窗口后,无需再对其作后续处理(即不用释放这个对象)。最后一行来自于 IDE 提供的模板:windo

39、w makeKeyAndVisible;这行代码会让窗口现已含有 的视图显示在屏幕上。之所以在窗口显示之前把视图添加进去,是为了防止用户在实际内容显示前看到短暂的白屏。3.4.5 内务处理做些什么 还剩几个任务:导入视图控制器头文件,合成存取方法,在 dealloc 方法中释放视图控制器(遵循内存管理规则里面的规定)。请在应用程序委托类的实现文件(即 HelloWorldAppDelegate.m)中执行下述操作:请在文件的顶部导入 MyViewController 的头文件:#import MyViewController.h 请在类的 implementation 代码块中通知编译器为视图

40、控制器合成存取方法:synthesize myViewController;请在 dealloc 方法起始处释放视图控制器:myViewController release;3.4.6 实现源码列表 为确保正确,请确定 的 HelloWorldAppDelegate 类的实现(即 HelloWorldAppDelegate.m 文件)如下所示:#import MyViewController.h#import HelloWorldAppDelegate.h implementation HelloWorldAppDelegate synthesize window;synthesize myV

41、iewController;-(void)applicationDidFinishLaunching:(UIApplication*)application MyViewController*aViewController=MyViewController alloc initWithNibName:MyViewController bundle:NSBundle mainBundle;self setMyViewController:aViewController;aViewController release;UIView*controllersView=myViewController

42、view;window addSubview:controllersView;window makeKeyAndVisible;-(void)dealloc myViewController release;window release;super dealloc;end 3.4.7 测试你的应用程序 现在可以测试应用程序。编译并运行工程(即点击 Build Build and Run,或者点击 Xcode 工具栏的 Build and Run 按键)。应用程序应能通过编译,不会报告错误。然后将在模拟器中再一次看到白色的屏幕。3.5 查看 Nib 文件 Interface Builder 用于

43、创建并配置 nib 文件。本节描述两个重要的概念:插座变量(outlet)以及文件拥有者代理对象。3.5.1 使用 Interface Builder Interface Builder 用于创建并配置 nib 文件,需使用 Interface Builder 创建用户接口。Interface Builder并不生成源码,而是让 直接操作对象,并将这些对象保存在一份被称为 nib 文件的档案。术语:术语:虽然虽然 Interface Builder 文档的扩展名可能是“文档的扩展名可能是“.xib”,但历史上,其扩展名是“,但历史上,其扩展名是“.nib”(“”(“NextStep Inter

44、face Builder”的首字母缩写),因此人们就俗称其为“”的首字母缩写),因此人们就俗称其为“Nib 文件”文件”。程序运行时会加载 nib 文件,解档文件中的对象并且将其恢复到被保存至文件那一瞬间的状态-包括对象间的所有关联。3.5.2 Nib 文件包含些什么 请双击 Xcode 中视图控制器的 XIB 文件(即 MyViewController.xib 文件),Interface Builder 会为 打开该文件,如图 3-11。图 3-11 NIB 文件 文件包含三个对象,文件拥有者代理,第一响应者代理以及一个视图。视图和 XIB 文件窗口分开显示,以便于 对视图进行编辑。3.5.

45、3 文件的拥有者 Interface Builder 文档中的文件拥有者对象和添加进去的其他对象不同。它不是在加载 nib 文件的时候创建,并且它会被设置为用户接口的拥有者通常情况下,用户接口拥有者负责加载接口。如果 需更加详尽的资料,请参看资源编程指南。在 的应用程序中,文件的拥有者是 MyViewController 的实例。Interface Builder 需要知道文件拥有者是什么类型的对象,这样它才能让 在文件拥有者和其他对象之间建立恰当的关联。可以利用 Identity Inspector 来告诉 Interface Builder 该对象所属的类。实际上,当 nib 文件伴随着视

46、图控制器类一同被创建出来时,nib 文件中的文件拥有者的类型就已被设置完成。不过现在,了解一下查看器对有很大好处。请在 Interface Builder 文档的窗口中选择文件拥有者的图标,然后选择 Tools Identity Inspector,这样 Identity inspect 就会显示出来,如图 3-12 所示。图 3-12 myViewController 属性 Class Identity 中的 Class 字段的值应该是 MyViewController。该值只是向 Interface Builder 承诺文件拥有者是该类的实例,把该字段设置成某个类并不能保证文件拥有者就是所

47、设的类的实例。文件拥有者的类型取决于加载 nib 文件的时 所设置的对象。如果它是其他类的实例,则 nib 文件中建立的关联就无法正确建立。3.5.4 如何使用视图插座变量 可以使用查看器面板来查看-建立或打断-一个对象的关联。请在 Interface Builder 文档窗口中按住 Control 键并点击文件拥有者,这样就可以在屏幕中显示一个半透明的面板,面板里显示了文件拥有者的关联,如图 3-13 所示。图 3-13 插座变量的使用 目前,文件拥有者只关联视图控制器的 view 插座变量。一个插座变量就是一个属性(通常是一个实例变量),只不过这个属性和 nib 文件中的某个项关联在一起。

48、此处的关联表明当 nib 文件被加载并且 UIView 的实例解档之后,视图控制器的 view 实例变量会被设定指向 nib 文件中的视图。3.5.5 如何加载 Nib 文件 视图控制器在 loadView 方法中会自动加载 nib 文件。加载哪个文件呢?请回想一下,在initWithNibName:bundle:方法的第一个参数已指定所要加载的 nib 文件的名称了。(请参看“创建一个视图控制器实例”一节)。通常情况下,在视图控制器整个生存过程中,loadView 方法只调用一次,目的是为了创建视图。当 调用视图控制器的 view 方法时,如果视图尚未被创建出来,则控制器会自动调用自己的 l

49、oadView 方法。(如果视图控制器由于接收到内存警告而清除了自己的视图,则在必要的时候,loadView 方法会被再次调用以创建视图)。如果希望编程创建视图控制器的视图,则可以重载 loadView 方法,并在 自己的实现中创建视图。如果 使用 initWithNibName:bundle:方法初始化一个视图控制器,但是希望在视图加载之后执行附加配置,则应该重载控制器的 viewDidLoad 方法。可以使用一个 NSBundle 实例自行加载 nib 文件。3.5.6 测试应用程序 为了确信应用程序可以正确执行,可以把视图的背景色设置成其他颜色(非白色),并在程序运行后验证新颜色是否显示

50、。(1)请在 Interface Builder 中选择视图,然后选择 Tools Attributes Inspector,这样屏幕就会显示Attributes inspector,如图 3-14 所示。(2)请点击 Background 选色板上的方框,让颜色面板显示在屏幕上。然后在其中选择一种不同的颜色。图 3-14 视图属性设置 (3)保存 nib 文件(4)编译并运行工程(请点击工具栏中的 Build and Go 按键)。应用程序应该可以正确编译,而后应该可以再次在模拟器里看到具有恰当颜色的屏幕。(5)请把视图的背景颜色恢复成白色并保存 nib 文件。3.6 如何配置视图 Inte

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 技术资料 > 其他杂项

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁