当前位置:文档之家› Cocoa 是什么?

Cocoa 是什么?

Cocoa 是什么?

Cocoa 是Mac OS X 操作系统的应用程序环境之一,是与 Carbon 和 Java 处于同一层的环境。它包含一组面对对象的软件库以及一个运行环境,而且它还与其它的应用程序环境共用一个集成开发环境。

本篇编程主题延伸了这个定义,描述了 Cocoa 的意图,能力和物理形式。作为一个开发人员阅读此篇Cocoa 功能介绍是理解 Cocoa 的最基础的第一步。

重要

本篇编程主题只是初步完成。尽管文中的内容是准确的,但是在将来有可能会更新。

前提条件

这个编程主题中使用的许多名词和概念是Mac OS X 的基础知识。您可以阅读“系统概览”来理解掌握这些名词和概念,您还可以阅读其它第三方的操作系统技术介绍文章。

Cocoa 介绍

与所有的应用程序环境一样, Cocoa 拥有两个面孔;它有一个运行时间外观和一个开发外观。在它的运行时间外观里, Cocoa 应用程序呈现给用户 Aqua 的界面并且与其它的操作系统可视部分: Finder ,Dock 以及所有其它环境中的应用程序紧密结合。在融入到以及成为用户体验的无缝的一个组成部分过程中, Cocoa 在它的运行时间外观里表现优秀。

但是开发人员对它的开发外观更加感兴趣。 Cocoa 是一整套集成的面对对象的软件模块-类-,它允许开发人员快速创建稳定的功能完善的Mac OS X 应用程序。这些类是可以重用和修改的软件构造模块;开发人员可以直接使用它们或者也可以根据他们自己的需求扩展这些类。 Cocoa 的类满足几乎所有可以想像到的开发需求,从用户界面对象到 Rendevnous 网络,以及预料不到的地方,您可以非常容易的创建一个已经存在的类的子类来满足需求。

Cocoa 拥有一个区别于所有其它的面对对象开发环境的截然不同的起源。自从 1989 年它首次作为NeXTSTEP 露面至今,它一直被完善和测试(请参考“历史简介”)。它的优美且强大的设计完美适用于快速开发各种软件,不仅仅应用程序还有命令行工具,插件,以及各种类型的“包”。 Cocoa 给了您的应用程序很多免费的功能和外观,为您节省了更多的时间用来开发那些独特的功能。(要了解 Cocoa 提供了哪些更详细的内容,请参考“ Cocoa 应用程序的功能”)。

您在开发 Cocoa 软件时有可能使用几种编程语言。主要的语言是 Objective-C ,它有自己的 Cocoa 运行时间。 Objective-C 是 ANSI C 的一个超集,它扩展了特定的语法和语意功能(从 Smalltalk 衍生出来)来支持面对对象的编程。添加的不多的约定都比较简单而且容易学习和使用。因为 Objective-C 以 ANSI C 为基础,您可以自由的混合使用纯 C 语言代码和 Objective-C 代码。除此之外,您的代码可以调用在非Cocoa 编程界面里,例如 Carbon 和 BSD ,定义的函数。您甚至可以混合 C++ 代码和 Cocoa 代码并且把它们链接到同一个执行代码里。最后, Cocoa 通过一组并行的 Java 类和一个桥接 Java 接口到它们相应的 Objective-C 实现的机制来支持 Java 语言。 Cocoa 的 Java 口味允许您混合(有限制的)纯Java 工程和 Cocoa 工程。

Cocoa 的核心类库被包装为两个框架,基础工具箱和应用工具箱。与其它所有框架一样,这些工具箱包含除了一个动态共享库(或者有时几个兼容版本的库)以外,还有头文件, API 文档以及相关的资源。基础工具箱和应用工具箱的二重唱反映了 Cocoa 编程接口按照与图形用户界面有无关系而被分为不同的类

组。这两个框架是任何最终产品为应用程序的 Cocoa 工程的基石。Mac OS X 还发布了几个小的框架,它们很好的展示了 Cocoa 编程接口,例如屏幕保护和地址簿框架,而且在将来还会添加更多到操作系统里。请参考“ Cocoa 框架”获得更多信息。

Cocoa 在Mac OS X 中的位置

如果您曾经浏览过苹果开发联盟网站(https://www.doczj.com/doc/0215623057.html, ),您有可能已经看到过下面图 1-1里面的Mac OS X 系统架构图。

图1-1 Mac OS X 架构展望图

这张图唯一的目的就是:给那些不熟悉Mac OS X 人清楚的描述出系统的主要组件和相互之间的关系。但是这个简化漏掉了许多重要的细节并且使其它一些细节变的模糊不清。这些细节对于展示 Cocoa 是怎么与其它的部分共存于Mac OS X 中作用重大。

图 1-2把 Cocoa 放在架构图示中更加准确的位置。这个图把 Mac OS X 分为一系列软件层,从最底层的 Darwin 一直到各种应用程序环境;中间的两层分别代表包含在两个主要的伞状框架里的系统软件,这两个框架是“核心服务”和“应用服务”。通常在这张图里一层中的一个模块依赖于它下面的层。

图 1-2 Cocoa 在Mac OS X 的架构中

在某些部分,这个图与上一张图很接近。例如,负责绝大多数 Aqua 用户界面渲染工作的系统模块-Quartz (在核心图形框架中实现)是应用服务层的一部分。并且在这个架构层状结构的底层是 Darwin ;Mac OS X 中全部组成部分,包括 Cocoa ,最终都依赖 Darwin 才能工作。

但是如果您更加仔细观察,在 Cocoa 单独或者成组的类以及在伞状框架中特定的子框架的地方,您可以看见 Cocoa 不是与Mac OS X 其它的部分有特殊的依赖关系就是用它的接口把底层的技术暴露出来。图1-3显示了一些依赖关系和暴露的情况。

注意:尽管 Cocoa 以来于特定的框架,它不仅仅只是位于这些框架的上面。在某些情况下, Cocoa 是其它的框架(例如 Carbon )的同级而且甚至可以做一些这些同级框架无法做到的事情。 Cocoa 不仅仅是处于许多底层技术之上的一个面对对象的层。

图 1-3 架构图放大-主要的依赖关系

苹果仔细的设计了 Cocoa 以使得应用程序通常需要的功能可以通过 Cocoa 的编程接口访问底层的技术来实现。但是如果您需要一些 Cocoa 编程接口没有暴露出来的功能,或者如果您需要更加仔细的控制您的应用程序,您可以直接使用一个底层的框架。(一个主要的例子是核心图形;通过调用它的函数和一些OpenGL 的函数,您的代码可以画比使用 Cocoa 画图方法更加复杂而且颜色细微的图片)。幸运的是,使用这些比较底层的框架不是什么问题,因为大多数非独立框架的编程接口是使用标准的 ANSI C 写的,而 Objective-C 语言是 ANSI C 的一个超集。

注意:这个架构概观的目的不是把每一个 Cocoa 的特殊的依赖关系或者 Cocoa 与Mac OS X 其它部分的接口独立开来。事实上,这个图突出了更加吸引人的部分以给您一个框架架构上下文的一个基础概念。

Cocoa 主要依赖的和通过它的类和方法暴露出来的底层框架有核心基础( Core Foundation ), Carbon ,核心图形( Core Graphics - Quartz ),启动服务( Launch Services )和核心打印(打印子系统):

?核心基础。许多基础框架的类都基于相对应的核心基础模糊类型。这个紧密的关系使得“过桥免费”

-在兼容的核心基础和基础类型之间的类型转换-变的可能。相应的一些核心基础的实现是基于Darwin 层中的 BSD 部分的。

?Carbon. Cocoa 为了 Carbon 提供的一些服务而涉足 Carbon 。这是因为处于核心服务和应用服务层里的各种 Carbon 框架作为系统范围的服务而存在。 Carbon 核心是这些框架里一个非常重要的一个;例如,它有文件管理器,而文件管理器是 Cocoa 用来转换各种不同文件系统的工具。?核心图形。 Cocoa 绘画和图像类是紧密的基于(非常自然的)核心图形框架的,而核心图形框架实现了 Quartz 和窗口服务器。

?启动服务。 NSWorkspace 类暴露了底层的启动服务的功能。 Cocoa 也使用启动服务中的应用程序注册功能来获取与应用程序和文档相关联的图标。

?打印核心。 Cocoa 打印类给打印子系统封装了一个面对对象的界面。

除此之外, Cocoa 使用 Carbon 环境的文本编码转换服务做一些字符串编码的转换。不同的 Cocoa 方法也为电源管理暴露了部分 I/O 工具箱框架;为 QuickDraw 画图暴露了部分 QuickDraw (QD) 框架;为苹果事件处理而暴露了部分苹果事件( AE )框架;以及为支持字体暴露了部分 ATS 框架。

Cocoa 应用程序的功能

您有可能一行代码都不用写就创建一个 Cocoa 的应用程序。在 Xcode 里创建一个新的 Cocoa 应用程序工程然后编译运行这个工程。就这么简单,当然,这个应用程序不会做什么事情,至少不会做什么有趣的事情。但是这个超级简单的应用程序在被双击后还是会启动,在 Dock 里显示它的图标,显示它的主菜单和窗口(标题是“窗口”),响应隐藏命令,与其它运行的应用程序相处融洽,还会响应退出命令。您可以移动和关闭窗口,还可以改变窗口的尺寸,或者把它最小化。您甚至可以窗口里空白的内容。

试着想一下您可以用很少的代码做什么。

从编程工作量来讲, Cocoa 给了您,一个开发人员,很多免费的东西还有很多便宜的东西。当然,要想成为一个多产的 Cocoa 开发人员意味着您要熟悉新的概念,设计模式,编程接口以及开发工具,而且这些工作并不是可以忽略不计的。但是熟练度会产生更大的生产力。编程很大程度上变为一个工作,把 Cocoa 提供的的编程模块与用户自定义的对象和代码组合在一起。用户自定义的对象和代码定义了您的程序特定逻辑以及连接整个程序的各个部分。

下面的内容简单的列出了 Cocoa 是怎样使您在不用花费很多精力(有时候甚至一点都不用)的情况下为您的应用程序添加功能的:

?基础应用程序框架- Cocoa 为事件驱动的行为和应用程序,窗口以及工作空间管理提供了基础设施。在大多数情况下,您不需要直接处理事件或者发送任何绘图命令给一个渲染库。

?用户界面对象- Cocoa 为您的应用程序用户界面提供了一整套丰富的已经制作好的对象。这些对象绝大多数您都可以在 Interface Builder 的模板中找到,Interface Builder 是一个设计用户界面的开发应用程序;您可以很方便地从模板窗口里拖拽一个对象到您的设计用户界面里,配制它的属性,然后建立它与其它对象的连接。(而且,当然,您始终可以在程序里事例化,配制以及连接这些对象。)下面是一些 Cocoa 用户界面对象的例子:

buttons drawers

radio

windows text

fields

sheets tab views table views browsers

pop-up lists sliders image views color wells

combo boxes scroll views text views steppers

?

?除此之外, Cocoa 还具有支持用户界面的技术,包括那些支持“万能辅助”,执行身份鉴定以及方便在用户界面里和用户自定义对象中建立对象之间的连接的技术。

?

绘图和图像- Cocoa 通过使用一个框架锁住图像聚焦以及标识视图(或者视图的部分)为“ dirty ” 来达到高效的绘图的目的。它包括了编程工具用于描画贝塞尔曲线,进行仿射变换,编辑图像,并且创建图像的多种代表方式。

系统交互- Cocoa 赋予您的应用程序一些方法用于和文件系统,工作空间和其它应用程序交互(以及使用文件系统,工作空间和其它应用程序的服务)。

数据交换- Cocoa 通过使用拷贝粘贴和拖放模式以及“服务”菜单简化了在一个应用程序之内和应用程序之间的数据交换。

性能-为了提高您的应用程序的性能, Cocoa 为多线程,空闲时间处理,惰性资源装载,内存管理和执行循环操作提供了编程支持。

基于文档的应用程序- Cocoa 定义了一个架构来支持那些有可能使用无穷多文档,每一个文档都包含在它自己的窗口里,的应用程序(例如,一个字处理程序)。事实上,如果您选择“基于文档的应用程序”工程类型,这种类型应用程序的许多组件已经为您创建好了。

脚本-通过属性列表和一组 Cocoa 支持类,您可以使得您的应用程序支持脚本;也就是,它可以响应AppleScript 脚本发送的命令。应用程序也可以运行脚本或者使用单独的苹果事件发送命令给其它的应用程序或者从其它的应用程序接收数据。结果是,每一个可以使用脚本控制的应用程序能够为用户和其它应用程序提供服务。

国际化- Cocoa 使用了一种厉经数年精炼的国际化和本地化方法。这种方法基于用户语言偏好的一个列表,它把本地化的资源放在应用程序的包里。它还提供了工具和编程界面来创建以及存取本地化字符串。还有,在 Cocoa 里文本操作在缺省情况下是基于 Unicode 的,于是这也是 Cocoa 国际化宝贵资产之一。

“撤消”管理-您可以在“撤消”管理器里注册用户动作,“撤消”管理器就会负责在用户选择相对应的菜单项目时撤消动作(以及重做动作)。这个管理器在不同的堆栈里分别保存“撤消”和“重做”操作。

文本- Cocoa 提供了一个先进的文本系统允许您做从最简单的文本处理(例如,显示一个可编辑文本的文本视图)一直到非常复杂的,例如字距调整,连字控制,拼写检查以及嵌入图片。

打印-与文本系统非常相似,打印的架构允许您打印文档和其它应用程序的内容,使用一系列控制和高级选项。在最简单的层次,您可以缺省打印任何视图的内容。在一个更加复杂的层次,您可以定义打印内容的内容以及格式,控制打印任务的执行以及给打印面板添加一个附属视图。

预置-用户预置系统基于一个系统范围的数据库,在这个数据库里您可以存储全局以及应用程序特定的预置。

网络- Cocoa 包括了一个分布对象的架构允许一个 Cocoa 进程与同一台计算机或者另外一台计算机上的另一个进程通信。这个架构还为您的应用程序集成 Rendezvous (零配制网络协议)能力提供了编程界面。

多媒体- Cocoa 为 QuickTime 视频和基础音频能力提供了支持。

开发环境

接下来的章节将探讨 Xcode , Interface Builder 和其它应用程序,工具,以及其它的组成Mac OS X 集成开发环境的资源-特别着重介绍 Cocoa 。

内容:

介绍

Xcode

Interface Builder

AppleScript Studio

其它开发工具

介绍

如果说 Cocoa 具有自己的开发环境可能不够准确。首先,编程人员可以使用苹果的主要开发应用程序:Xcode 和 Interface Builder 来开发其它Mac OS X 应用程序环境的软件,比如说 Carbon 软件。还有,不使用 Xcode 和 Interface Builder 开发 Cocoa 应用程序是可能的。例如,您可以使用 Metrowerks 的CodeWarrior 来管理,编译以及调试 Cocoa 工程。并且,如果您想要更加专业,您可以使用 Emacs 等文本编辑器,在命令行下使用 make 文件创建应用程序,并且在命令行使用 gdb 调试器调试应用程序。

但是 Xcode 和 Interface Builder 是开发 Cocoa 软件的首选应用程序。它们的产生时间刚好与 Cocoa 是一致的,于是在它们工具与框架之间有一个良好的兼容性。 Xcode 和 Interface Builder 一起使得设计,管理,编译和调试 Cocoa 软件工程异常容易。除此之外, AppleScript Studio 扩展了这些能力,它帮助您创建脚本可控制的 Cocoa 应用程序和使用 AppleScript 控制其它应用程序的应用程序。

Xcode

Xcode 是苹果Mac OS X 的集成开发环境( IDE )的发动机。它是一个应用程序,负责绝大多数工程的细节,从工程的开端一直到部署。它允许您

?创建和管理工程,包括制定目标需求,依赖关系和编译风格

?在编辑器里使用语法颜色和自动缩进等功能编写源代码

?浏览和搜索工程里的组件,例如头文件和文档等

?编译工程

?在一个图形界面的源代码级的调试器里调试工程

Xcode 编译用C, C++, Objective-C, Objective-C++, 和 Java 编写的源代码工程。它产生所有Mac OS X 上支持的可执行代码类型,包括命令行工具,框架,插件,内核扩展,包,和应用程序。 Xcode 允许几乎无限制的自定义编译和调试工具,执行代码打包(包括信息属性列表和本地化的包),编译过程(包括拷贝文件,脚本文件和其它编译阶段),以及用户界面(包括分开的,多视图的代码编辑器)。如果您的代码在一个 CVS 库里, Xcode 提供了源代码控制,允许您添加文件到库里,确定修改,获得更新的版本,以及比较版本。

图 3-1在 Xcode 里展示了一个工程的例子

图 3-1 Xcode 中的 TextEdit 工程例子

Xcode 特别适合于 Cocoa 开发。在您创建一个工程的时候, Xcode 使用对应于 Cocoa 工程类型的工程模版为您设置一个起始的开发环境,工程类型有:应用程序( Objective-C 或者 Java ),基于文档的应用程序( Objective-C 或者 Java ),工具,包,和框架。 Xcode 使用 GNU C 编译器( gcc )编译 Cocoa 软件,使用 GNU 源代码级别调试器( gdb )调试这些软件。 gcc 和 gdb 在 Cocoa 还是NeXTSTEP (请参考“历史简介”)的时候就被用于 Cocoa 的开发,经过若干年一直被精雕细琢,扩展,并且调优以支持 Cocoa 二进制代码的编译和调试。 Xcode 还有一个类浏览的功能,您可以察看所有输入的 Cocoa 框架和任何您的自定义类,这些类按照它们继承关系排列;在类浏览器里您可以请求任何类的文档。

Xcode 与另一个主要开发应用程序, Interface Builder ,紧密结合。在 Interface Builder 里您可以定义一个类( superclass , outlets ,和动作)并且为您的工程里的每个类生成框架头文件和源文件。在 Xcode 里,您可以添加 outlets 和动作到您自定义的类,然后让 Interface Builder 把这些实体输入到 nib 文件里。

注意:简要的说, outlet 是一个一个对象与另外一个对象之间的一个归档连接(而且被定义为一个对象的一个实例变量)。一个动作是,当另外一个对象例如一个按钮或者滚动条被操作的时候,一个对象里被调用的一个方法(通常是一个自定义对象),这个对象被称作为目标; Interface Builder 也归档目标和另一个对象(称之为控件)之间的连接。要获得更多有关 outlets ,目标,和动作的信息,请参考“ Outlets ”和“目标-动作模式”。

要获得更多信息,请参考 Xcode 在苹果开发人员联盟网站(https://www.doczj.com/doc/0215623057.html,/developer/ )上的Xcode 主页,在那里您可以链接到 Xcode 最新的文档。

Interface Builder

第二大 Cocoa 工程主要的开发应用程序是 Interface Builder 。就象它的名字一样, Interface Builder 是一个图形工具用于创建用户界面。 Interface Builder 从 Cocoa 开端于 NeXTSTEP 的时候就存在了。从那时开始,它就因为是同类应用程序中的佼佼者而被广泛接受认可。所以它与 Cocoa 紧密结合不足为奇。除此之外,您可以使用它去创建 Carbon 应用程序用户界面。

Interface Builder 有三个主要设计元素:

?Nib 文件。一个 nib 文件实际上是一个文件包裹(一个不透明的目录),它包含出现在用户界面上的对象,这些对象以归档的方式保存。实质上,这个归档是一个对象图像,它包含每个对象的信息,包括它在屏幕上的尺寸和位置(如果一个窗口)或者在窗口中的尺寸和位置。在 Cococa 应用程序里的 Nib 文件也包含自定义类的代理引用和对象间连接的信息。当您在 Interface Builder 里创建并且保存一个用户界面时,所有重新创建界面所需的信息被保存在 nib 文件里。一个 nib 文件可以包含在界面里使用的图片和声音文件。

Interface Builder 把一个 nib 文件保存在 Cocoa 工程里的一个本地化的目录里;当这个工程编译时, nib 文件就被拷贝到新建立的包里一个对应的本地化的目录里。(于是 nib 文件就提供了一种很容易本地化用户界面的方法。)一个 Cocoa 应用程序通常-就是使用 Xcode 创建-有一个主 nib 文件,这个文件在应用程序启动时自动被装载并且显示。主 nib 文件包含应用程序的主菜单并且有可能包含一个或者多个窗口。您的应用程序可以根据需求装载其它的 nib 文件(例如预置窗口)。

Interface Builder 在一个 nib 文件窗口里显示一个 nib 文件的内容。 Nib 文件窗口还允许您定义用户类并且检查对象间的连接。

?模板。 Interface Builder 的模板窗口包含了多个面板,或者称之为“模板”,每个里面包含了一组相关的用户界面对象。您通过从模板里拖拽对象到适当的表面创建一个用户界面,而不用管这些表面是屏幕,一个窗口,一个某种类型的视图,或者主菜单。(模板对象不一定本身是可见的,但是它们一定会在某些方面影响界面。)当一个对象从一个模板里被拖拽出来时, Interface Builder 创建那个对象的一个缺省的实例;它是一个真正的 Cocoa 对象,而不是一些在运行时间时创建的代替一个实例的代理对象。如果您希望,您可以在 Interface Builder 的模板里放入您自己的自定义对象。

?检视窗口。 Interface Builder 有一个用户界面对象的检视窗口(指定为信息窗口)。信息窗口由一系列可以选择的面板组成,这些面板用于设定对象的初始属性和尺寸(尽管尺寸和许多属性可以通过直接操作来设置)。其中一个面板允许您建立对象间的连接,另外一个允许您把一个应用程序工具箱超类替换为一个自定义类。其它的更特定的面板允许您使用用户界面对象关联帮助标签,

AppleScript 事件处理函数,以及 Sherlock 频道。

图 3-2显示了在 Interface Builder 中打开的一个 nib 文件,还有相关支持窗口。

图3-2 Interface Builder 中的 TextEdit 的预置窗口

在 Interface Builder 里创建一个用户界面的步骤非常直接:

1. 拖拽一个窗口或者面板对象到屏幕上(一个面板就是一个对话框或者二级窗口)。

2. 设置这个窗口的初始(或者永久)位置,尺寸,和属性。

3. 拖拽对象例如文本区,按钮,表格视图,和弹出列表到窗口上,或者放到先前放置的视图上。

4.设置这些对象的初始(或者永久)位置,尺寸,和属性。

5.定义您的应用程序的自定义类。

您可以在 Interface Builder 里做这件事或者通过装载 Interface Builder 曾经创建过的头文件。当您

定义一个自定义类的时候, Interface Builder 允许您指定它的 outlet 和动作。

6.连接 outlet 到它们所代表的对象然后把动作连接到目标对象里适当的方法。

7.存储然后测试界面。

Interface Builder 具有一个功能帮助您在任何设计阶段测试一个界面(除了自定义的行为外)。

8. 为每个用户自定义类创建头文件和源文件;这些文件出现在相关联的 Xcode 工程里。

Interface Builder 具有一项功能,它在您移动或者改变每个定位的对象时用短暂的蓝颜色的线来显示移动和改变的大小是否遵循 Aqua 人机界面准则。这些符合包括推荐的尺寸,对齐,和与用户界面上的其它对象以及与窗口边界的相对位置。

要获得更多关于 Interface Builder 的信息,请参考应用程序帮助文档或者 Interface Builder 在苹果开发联盟网站(https://www.doczj.com/doc/0215623057.html, )上的主页。

AppleScript Studio

Mac OS 若干年以来的一个标志性的功能就是用户可以用 AppleScript 语言编写的脚本来控制应用程序。很多用户发现这个功能是不可缺少的,因为它允许这些用户把涉及多个应用程序的一系列复杂的相关的操作串在一起。 AppleScript 的功能被带到了Mac OS X 。 AppleScript Studio 是一个创建使用AppleScript 脚本去控制复杂用户界面的 Cocoa 应用程序的开发技术。

AppleScript Studio 结合了 AppleScript , Xcode , Interface Builder ,和 Cocoa 的要素以提供一个创建 AppleScript 解决方案的高级环境。它允许您开发应用程序来完成以下任务:

?执行 AppleScript 脚本

?控制应用程序的用户界面

?控制那些响应脚本命令的应用程序或者响应脚本命令的操作系统的部分

因为 AppleScript Studio 把 AppleScript 与 Xcode , Interface Builder ,和 Cocoa 集成在一起,脚本编程人员可以利用它们特殊的优势和功能。他们可以从 Interface Builder 模板里拖拽一套丰富的用户界面对象然后按照自己的喜好去自定义这些对象。他们可以得到内置的 Aqua 人机界面规则的支持。而且他们可以使用多个目标和编译步骤来编译和维护复杂的工程。

这个开发环境使得一些大大超出原有 AppleScript 脚本开发应用程序 Script Editor 的功能成为现实。这些功能有:

?创建任意大的脚本

?脚本中搜索以及替换

?使用执行变量单步脚本调试

?方便存取脚本中的处理函数和参数

?一个灵活的字典查看窗口方便使用应用程序脚本术语

要获得更多信息,请参考 AppleScript 文档的技术页。

其它开发工具

尽管 Xcode 和 Interface Builder 是您开发 Cocoa 应用程序的主要工具,还有几十个其它的工具随时听候您的调遣。您一定会在某些开发阶段发现这些辅助工具和命令行工具对您很有帮助。

本节将评价这些辅助工具并且简要讨论一些命令行工具。然而,命令行工具实在是太多了,即使是一个浓缩的概括也已经超出了本篇文档的范围。对于 /usr/bin 和 /usr/sbin 目录下的工具您最好参考它们的说明书页( man pages )。要察看说明书页,在终端界面里输入 man 以及工具的名字。在 /Developer/Tools 下面还有一些苹果开发的命令行工具。

性能工具

下面的应用程序用于测量和分析程序性能的方方面面。它们位于 /Developer/Applications 目录里。

?Sampler 分析一个程序的运行行为和它的内存分配情况。就象它的名字一样, Sampler 定时取样应用程序的函数调用堆栈。在一次取样任务结束后,它会给您显示那些遇到次数最多的函数或者方法。这些信息可以帮助您定位那些消耗大块 CPU 时间的函数或者方法以及分配过多内存的函数或者方法。

?ObjectAlloc 在任意程序里跟踪内存分配和释放。这些历史数据揭示了重复分配行为和整体分配走向。对于 Objective-C 代码来说, ObjectAlloc 记录下每次copy, retain, release, 以及 autorelease 方法的激活以及每次 alloc 的激活。它还记录了对应于这些方法的核心基础函数以及通过 malloc (以及相关的)函数分配的内存。

?MallocDebug 显示您的程序里当前分配的所有内存块,按照内存分配时间的调用堆栈分类。看一眼您可以了解您的应用程序消耗了多少内存,这些内存从什么地方分配的,那些函数分配了大量的内存。 MallocDebug 还可以找到程序里没有引用的分配的内存,这样就可以帮助您查找泄露以及跟踪到这些内存到底是在什么地方分配的。

?QuartzDebug 是一个帮助您调试您的应用程序显示方式的工具。它对于那些做大量描画和图像的应用程序尤其有帮助。 QuartzDebug 有几个调试选项,包括下面的:

o autoflush 描画,它在每次描画操作后刷新图形上下文的内容。

o一个模式,把屏幕的显示范围在更新之前涂画成黄色

o一个选项,拍系统范围的窗口列表的一个静态截图,显示出每个窗口的拥有者和每个窗口消耗的内存数量。

?Thread Viewer 显示一个进程里的线程的活动情况。它显示每个线程的活动的时间线,并且使用彩色标示。点击一个时间线,您可以得到在那点以前的活动轨迹的采样。

要分析性能,您还可以使用下面的命令行工具:

?top ,显示当前运行的进程的一个阶段采样的统计数据

?gprof ,生成一个程序的执行状态描述

?fs_usage ,显示文件系统存取统计数据

除此之外还有许多其它命令行工具用于性能分析。要得到更多在开发 Cocoa 应用程序时可以使用的性能工具和应用程序,以及概念和信息、技巧、与性能相关的策略,请参考性能编程主题。

其它工具

您一定会发现以下的应用程序(也位于 /Developer/Applications 目录)对 Cocoa 应用程序开发非常有帮助:

?Icon Composer (图标编辑)和 icns Browser (图标浏览)。对于应用程序和文档的图标,您可以使用图标编辑导入各种图像格式然后创建图标文件。您可以使用图标浏览应用程序来浏览一个图标的尺寸,颜色深度和位遮图。

?FileMerge 用可视化的方式比较文本文件(例如源代码文件,头文件,和属性列表文件等)并且提供了可选择的合并功能。

?Package Maker 打包应用程序(以及其它类型的软件)用于 Installer 应用程序的安装。

?Property List Editor 是一个用于创建和编辑 XML 和老的风格的属性列表的编辑器。

Cocoa 框架

接下来的段落总结了 Cocoa 的类和一些重要的框架的示意图,特别是核心框架 Foundation (基础)和Application Kit (应用程序工具箱)。

内容:

介绍

基础框架

应用程序工具箱

其它 Cocoa API 框架

介绍

是什么使得一个程序变成了一个 Cocoa 的程序?它其实不是编程语言,因为您可以在 Cocoa 开发中使用一些不同的语言。它也不是开发工具,因为您可以在命令行中(尽管这会是一个非常复杂和耗时的工作)创建一个 Cocoa 应用程序。所有 Cocoa 应用程序的共性(也就是使得它们与众不同的东西)是它们都由一些最终从根类, NSObject ,继承而来的对象组成,而 NSObject 最终基于 Objective-C 运行时间。这个解释对于所有的 Cocoa 框架同样正确。

注意 : 这个解释还需要做一点点澄清。首先, Cocoa 提供了另外一个根类, NSProxy ;但是, NSProxy 在 Cocoa 编程里很少被用到。其次,您也可以创建您自己的根类,但是这将是很大量的工作(需要您编写代码与 Objective-C 运行时间相交互),结果是可能得不偿失。

Mac OS X 包含了几个 Cocoa 框架,并且苹果和其它第三方开发商一直在发布更多的框架。尽管 Cocoa 框架有很多,有两个与其它的有很大的区别。基础( Foundation )和应用程序工具箱( Application Kit )是 Cocoa 的核心框架。您除非链接应用程序工具箱(以及使用它的类),否则您不能开发一个 Cocoa 应

用程序。你也不可能开发 Cocoa 任何类型的软件,除非您链接基础框架或者使用它的类。(链接这些框架是当您在链接 Cocoa 伞状框架时自动完成的)。基础和应用程序工具箱框架是 Cocoa 开发的基础,所有其它的框架都是次要的和可选的。

接下来的章节考察了这两个核心 Cocoa 框架的功能和类,并且简要描述了一些次要的框架。为了使得这些大的框架更加容易被掌握,对于基础和应用程序工具箱框架的介绍会按照功能组的体系分割为几十个类。尽管这些功能组有很深的逻辑基础,您可以按照其它方式把这些类分组。

基础框架

基础框架定义了一个类的基础层,这些类可以被任何类型的 Cocoa 程序所使用。区分基础框架和应用程序工具箱的类的标准是用户界面。如果一个对象既不出现在一个用户界面里,也不特意的被用来支持一个用户界面,那么它的类就属于基础框架。您可以仅使用基础框架创建 Cocoa 程序;这些程序可能是命令行工具和因特网服务器。

基础框架设计的初衷是:

?定义基础对象行为以及为例如内存管理,对象易变性和通知引进一致的约定。

?使用包技术和 Unicode 字符串支持国际化和本地化技术。

?支持对象持续。

?支持对象分发。

?提供一些操作系统独立的方法来支持可移植性。

?为编程基元提供对象包装或者等同物,例如数字数值,字符串以及集合。同时来包含了工具类用于调用底层系统实体和服务,例如端口,线程和文件系统等。

Cocoa 应用程序,由链接应用程序工具箱而定义,不可避免的也要链接基础框架。类的继承共享了同一个根类, NSObject ,而且许多应用程序工具箱的方法和函数使用基础框架对象作为参数或者返回值。一些基础框架类可能看起来像是为应用程序设计的,例如 NSUndoManager 和 NSUserDefaults ,但是它们包含在基础框架里,因为他们可以用在不涉及用户界面的地方。

基础框架范例和规则

基础框架为 Cocoa 编程引进了几个范例和规则来保证一致的表现和在一些特定情况下程序中的对象之间的期待结果。包括:

?对象拥有权和对象处理。不是使用一种自动的垃圾回收机制,基础框架实行了一种对象拥有权的规则,这个规则定义对象负责释放其它的它们创建的,拷贝的或者明确保留的对象。 NSObject (类和协议)定义了保留和释放对象的方法。自动释放池(定义了 NSAutoreleasePool 类)实现了一个延时释放的机制,从而使得 Cocoa 程序拥有了一个返回那些调用者不再负责任的对象的一致的约定。要获得更多关于对象拥有权和处理相关的信息,请参考内存管理。

?可变类的变体。许多基础框架的数值类和容器类拥有一个不可变类的可变的变体,而这个可变类始终是不可变类的一个子类。如果您需要动态的改变这样的一个对象的封装的数值或者成员,您要创建可变类的一个实例。由于它是从不可变类继承而来,您可以在不可变类型的方法中传递可变的实例。

?类簇。一个类簇是一个抽象类和一套私有具体的子类,抽象类表现为具体子类的伞状接口。依赖于上下文(特别是您用来创建对象的方法),一个适当优化过的类的实例会返还给您。例如 NSString 和 NSMutableString ,充当为为不同类型的存储需求而优化的多种私有子类实例的经纪人。经过若干年,整套的具体类已经改变了几次,但是应用程序并没有被破坏。

?通知。通知是 Cocoa 中一个主要的设计模式。它基于一个广播的机制,允许对象(被称为观察者)被一直通知其它的对象正在做什么或者在用户和系统事件里遇到了什么。通知的的发起对象可以不知道通知的观察者的存在或者身份。有几种通知的类型:同步的,非同步的以及分布的。基础框架通知机制由 NSNotification , NSNotificationCenter , NSNotificationQueue 和

NSDistributedNotificationCenter 类实现。要获得更多关于通知的信息,请参考“通知”。

基础框架类

基础框架类的继承关系开始于 NSObject 类,它(与 NSObject 和 NSCopying 协议一起)定义了基础对象属性和行为。要获得更多关于 NSObject 和基础对象行为的信息,请参考“根类”。

其余的基础框架内容包括及格相关的类的组以及一些单独的类。有代表基础的数据类型例如字符串和字节数组的类,排序其它对象的集合类,代表系统信息如日期的类,还有代表系统实体如端口,线程和进程的类。在图 4-1,图 4-2,图 4-3中的类继承关系表里描述了这些类组成的逻辑组以及它们之间的继承关系。

图 4-1基础框架类继承关系- Objective-C (第一部分)

图 4-2基础框架类继承关系- Objective-C (第二部分)

图 4-3基础框架类继承关系- Objective-C (第三部分)

这些图示逻辑上把基础框架的类按以下分类分为不同的组(并且指出其它关联):

?数值对象。数值对象封装不同类型的数据,提供数据的存取和数值的不同的操作方法。由于它们是对象,它们(以及它们所包含的数值)可以被存档和分发。 NSData 为字节流提供了面对对象的存储,而 NSValue 和 NSNumber 则为简单的向量数值的数组提供了面对对象的存储。 NSDate ,NSCalendarDate 和 NSTimeZone 类存储时间和日期。它们提供了用于计算日期和时间差异,用于以很多中格式显示日期和时间,以及用于根据在世界所处不同位置调整时间和日期的方法。

?字符串。 NSString 是另外一种类型的数值对象,它为使用一种特定编码的以空字符结尾的字节数组提供了面对对象的存储。它支持在 UTF-16 , UTF-8 , MacRoman 和许多其它编码之间转换字符串的编码。 NSString 还提供了方法用于搜索,合并和比较字符串,以及操作文件系统路径。

您可以使用法 NSScanner 对象来从一个 NSString 对象接收数字和单词。 NSCharacterSet (在图示里显示为一个结合类)代表一组被多个 NSString 和 NSScanner 方法使用的字符。

?集合。集合是一些对象,它们以一种特定的顺序方案存储和声明其它(通常是数值)对象。 NSArray 使用基于零的索引, NSDictionary 使用关键数值对, NSSet 提供了对象的非顺序存储

( NSCountedSet 使得集合与众不同)。通过使用 NSEnumerator 对象,您可以顺序存取一个集合的元素。集合对象是特性列表的重要组件,而且象其它所有对象一样,可以被存档和分发。

?操作系统服务。许多基础框架类方便您存取各种操作系统底层一些的服务,而且同时,把您从操作系统特质隔离开来。例如, NSProcessInfo 允许您查询一个应用程序运行所处的环境, NSHost 产生一个网络上的主机系统的名称和地址。您可以使用一个 NSTimer 对象按照固定的时间间隔发送一个信息给其它的对象,而 NSRunLoop 允许您管理一个应用程序或者其它类型的程序的输入资源。

NSUserDefaults 为一个全局(每个主机)和每个用户缺省数值(预置)系统数据库提供了一个编程的接口。

o文件系统和 URL 。 NSFileManager 提供了一个一致的界面用于文件操作,如创建,改名,删除和移动文件。 NSFileHandle 允许在一个更底的层次操作文件(例如,在一个文件

里搜索)。 NSBundle 查找存储在包里面的资源,并且能够动态的装载一些资源(例如, nib 文

件和代码)。您可以使用 NSURL 和 NSURLHandle 来代表,存储和管理数据的 URL 资源。

o进程间通讯。在这个分类里面的绝大多数类代表各种类型的系统端口,套接口和名称服务器,它们非常有助于实现底层 IPC 。 NSPipe 代表一个 BSD 管道,一个在进程之间的单

向通讯通道。

o线程和子任务。 NSThread 允许您创建多线程程序,同时各种锁类提供了通过竞争线程来控制进程资源的存取的机制。通过使用 NSTask ,您的程序可以把一个子进程分支出去执行

任务并且监视它的进展。

?通知。请参考通知类的总结“ 基础框架范例和规则”。

?存档和 serialization 。在这个分类里的类使得对象的分发和持续变的可能。 NSCoder 和它的子类(尤其是 NSArchiver ),与 NSCoding 协议一起通过允许类信息和数据存储在一起的方式代表了一个对象以独立架构方式包含的数据。

?Objective-C 语言服务。 NSException 和 NSAssertionHandler 提供了一个在代码中处理异常的面对对象的方法。一个 NSInvocation 对象一个 Objective-C 消息的一个静态的代表,您的程序可能保存这个消息然后用来在另外一个对象中调用一个消息。它被撤消管理器( NSUndoManager )和分布对象系统所使用。一个 NSMethodSignature 对象记录一个方法的类型信息并且在消息传递的时候使用。 NSClassDescription 是一个抽象类用于定义和查询一个类的关系和属性。

?脚本。在这个分类里的类帮助您的应用程序相应 AppleScript 脚本和苹果事件命令。

?分布对象。您可以使用分布对象类在同一台计算机或者网络上的不同的计算机上的进程之间通讯。

这其中的两个类, NSDistantObject 和 NSProtocolChecker 拥有一个根类( NSProxy )区别与其它 Cocoa 中的根类。

?网络。 NSNetService 和 NSNetServiceBrowser 类支持零配制网络架构,称作为Rendezvous 。 Rendezvous 是一个强大的发布和浏览一个 IP 网络上的服务的系统。

应用程序工具箱

应用程序工具箱是一个框架,它包含了您用来实现您的图形和事件驱动的用户界面的全部对象:窗口,对话框,按钮,菜单,滚动条,文本框等等,而且这个列表还在不断增加。应用程序工具箱为您处理所有细节的部分,它可以有效的在屏幕上描画,与硬件设备和屏幕缓冲区对话,在描画之前清楚屏幕的区域,以及裁剪视图。在应用程序工具箱里的类的数量在开始可能会吓您一跳。但是,绝大多数应用程序工具箱的类是支持类,您不会直接使用到它们。您也可以选择在什么层次上使用应用程序工具箱:

?使用 Interface Builder 去创建用户界面对象和您的应用程序控制对象之间的连接,控制对象通常是用于管理用户界面的用户自定义对象。在这种情况下,您需要做的全部就是完成您的控制类特别是实现那些类的动作和代理方法。例如,您可能需要实现一个方法在用户选择一个菜单项目时它被调用(除非这个菜单项目有一个缺省的可以接受的实现)。

?通过编程方式控制用户界面,这样您对应用程序工具箱的类和协议要更加熟悉。例如,如果允许用户把一个图标从一个窗口里拖拽到另外一个窗口需要您对 NSDragging 协议有所了解而且要使用NSDragging 编程。

?通过生成 NSView 或者其它类的子类来实现您自己的对象。在生成 NSView 的子类时,您使用图像函数编写您自己的描画方法。生成子类需要您对应用程序工具箱的工作原理有更深的了解。

应用程序工具箱概览

应用程序工具箱包含超过 125 个类和协议。所有的类最终都是从基础框架的 NSObject 类继承而来。图4-4和图 4-5中的一览表显示了应用程序工具箱的类的继承关系。

图 4-4 应用程序工具箱类继承关系- Objective-C (第一部分)

图 4-5 应用程序工具箱类继承关系- Objective-C (第二部分)

您可以看到,应用程序工具箱的继承关系树非常宽但是比较浅;在继承关系里最深的类离跟类只是五个父类的距离,而且绝大多数的类都比这个距离近的多。在这个继承关系树里一些主要的分支非常有趣。

应用程序工具箱里最大的分支的根是 NSResponder 类。这个类定义了响应者链,是一个响应用户事件的有序的对象列表。当用户点击鼠标按钮或者按下一个键,一个事件被产生并且沿着这个响应者链向上传递直到找到一个可以响应这个事件的对象。任何处理事件的对象必须从 NSReponder 类继承而来。应用程序工具箱核心类- NSApplication , NSWindow 和 NSView 都从 NSResponder 继承而来。

应用程序工具箱里第二大分支类从 NSCell 发展而来。关于这一组类值得一提的是它们几乎镜像了从NSControl 继承的类,而 NSControl 从 NSView 继承而来。对于响应用户动作的用户界面对象,应用程序工具箱使用了一个架构把工作在控制对象和单元对象之间区分开来。 NSControl 和 NSCell 类以及它们的子类定义了一套常用的用户界面对象例如:按钮,滚动条以及用户可以以图形化方式控制您的应用程序的一些方面的浏览器。一个控制对象与一个或者多个实现描画和事件处理的细节的单元对象相关联。例如,一个按钮同时包括了一个 NSButton 对象和一个 NSButtonCell 对象。

这个对于功能的区别的最主要的理由是允许 NSCell 类可以被 NSControl 类重用。例如, NSMatrix 和NSTableView 可以包含多个不同类型的 NSCell 对象。例外一个理由是更好的性能,因为单元对象对比控制对象要更为轻量级;一个具有四个单元的控件要比四个控件在做同一件事情时更少影响到性能。要获得更多关于控件和单元的信息请参考“控件和单元”。

控件和单元实现了应用程序工具箱的一个重要的设计模式:目标-动作范例。一个单元可以包含能够分辨当用户点击(或者作用与)单元的时候应该发送给一个特定对象消息的信息。当一个用户操作一个控件的

时候(例如通过点击在它上面的鼠标箭头),这个控件把需要的信息从它的单元分离开然后发送一个动作消息给目标对象。目标-动作允许您通过定义目标对象和调用的方法是什么来赋予一个用户动作一定的含义。您通常使用 Interface Builder 来设置目标和动作,做法是按住 Control 键从一个控制对象拖拽关系线到您的应用程序或者其它对象。您可以在程序里面设置目标和动作。

应用程序工具箱里另外一个重要的设计模式是代理。用户界面里的许多对象,例如文本区和表格视图,定义了一个代理。一个代理就是一个对象代表被代理对象或者与它协调动作。于是它就可以把应用程序特定的逻辑交给用户界面的操作。要获得更多关于代理,目标-动作和其它应用程序工具箱范例和机制的信息,请参考“与对象通信”。

接下来的章节简要介绍了应用程序工具箱和它的类以及协议的一些功能和架构的方方面面。它按照图 4-4和图 4-5中的类继承关系一览表把类分组。

普通用户界面类

对于用户界面的整体上的的功能,应用程序工具箱提供了一下类:

?全局应用程序对象。每个应用程序使用一个 NSApplication 的单一实例来控制主事件循环,跟踪应用程序的窗口和菜单,分发事件给合适的对象(也就是说,它自己或者它的一个窗口),创建顶层的自动释放池,以及接收应用程序级别事件的通知。一个 NSApplication 对象拥有一个代理(您分配的一个对象),它在应用程序启动和终止,隐藏或者被激活,应该打开用户选择的一个文件时会接到通知。通过设置应用程序对象的代理和实现代理方法,您不需要定义 NSApplication 的子类就可以自定义您的应用程序的行为。

?窗口和视图。窗口和视图类, NSWindow 和 NSView ,也是从 NSResponder 继承而来,于是在设计上会响应用户动作。一个 NSApplication 对象维护一个 NSWindow 对象的列表-每个应用程序的窗口有一个对象-而且每个 NSWindow 对象维护一个 NSView 对象的继承关系。视图的继承关系用于描画以及处理一个窗口里的事件。一个 NSWindow 对象处理窗口级别的事件,给它的视图分发其它的事件,并且为它的视图提供一个描画的区域。一个 NSWindow 对象也拥有一个代理允许您自定义它的行为。

NSView 是在一个窗口里显示的所有对象的一个抽象类。所有实现一个描画方法的子类使用图形函数; drawRect: 是您在创建一个新的 NSView 类时主要的需要覆盖的方法。

?面板(对话框)。 NSPanel 类是 NSWindow 的一个子类,您使用它来显示临时的,全局的,或者紧急的信息。例如,您应该使用一个 NSPanel 的实例而不是一个 NSWindow 的实例来显示出错信息或者询问用户对于值得注意的或者不寻常的环境的反应。应用程序工具箱为您实现了一些常用的对话框例如存储,打开和打印对话框,它们用于存储,打开和打印文档。使用这些对话框赋予用户一个在整个应用程序的常用操作中连贯的外观和体验。

?菜单和光标。 NSMenu , NSMenuItem 和 NSCursor 类定义了应用程序显示给用户的菜单和光标的外观和行为。

?分组及滚动视图。 NSBox , NSScrollView 和 NSSplitView 类为窗口中的其它视图对象或者视图集合提供了图形助理。使用 NSBox 类,您可以分组窗口里的元素以及环绕整个组描画一个边界。

NSSplitView 类帮助您在垂直和水平方向扩展视图,给每个视图分配一定数量的公共领地;一个滚动控制条帮助用户在视图间重新分配领地。 NSScrollView 类和它的帮助类, NSClipView ,提供了

相关主题
文本预览
相关文档 最新文档