第2讲 应用程序与框架

本书的目的是介绍开发iPhone应用程序的基础知识,但iPhone应用程序都是在Mac OS X的环境下开发的,掌握开发iPhone应用程序基础知识,首先要掌握开发普通的Mac应用程序的基础知识,这些都是开发iPhone应用程序基础知识的一部分。

本章将首先从几个基本概念入手介绍什么是应用程序,应用程序有哪些种类,开发iPhone应用程序时需要些什么。从而引出框架的概念,最后会介绍广泛使用在Mac OS X环境的重要框架——Cocoa框架。

2.1 关于应用程序

在学习这本书时,我想你已经在Mac计算机上使用过Mac OS X系统了吧,Mac OS X就是称为操作系统(Operation System)的软件。除了Mac OS X外,还有Windows,Linux,BSD,Solaries等操作系统为大家所熟悉。

如果Mac计算机上只安装了Mac OS X是不能做任何事情的,还必须安装Mac OS X软件包中的Safari,Finder等软件,这样我们才能完成上网浏览网页,进行目录管理等工作。

应用程序与操作系统在分工上到底在本质上有哪些不同呢?我们可以看到Mac计算机中的应用程序都具有漂亮的窗口,功能齐全的菜单,应用程序就是为用户提供这些功能的操作,而像在硬盘中保存、读取文件等多数应用程序必备的功能其实是由操作系统来完成的。

通俗来讲,应用程序就是替用户完成眼睛可以看到的工作,而操作系统则默默地干着底层但最关键的“脏活、累活”。

2.1.1 应用程序的种类

应用程序有各种类型,这里简要地介绍一下。

1. 桌面应用程序

桌面应用程序就是用户能在计算机桌面使用的应用程序。例如Safari,Mail,iChat就是桌面应用程序,Finder当然也是,Finder是Mac OS X中使用最频繁、最为用户所熟悉的应用程序了。

Mac计算机中的桌面应用程序都具有漂亮的窗口、丰富的菜单。通过这些菜单能完成各种操作,这些漂亮的窗口、菜单就是所谓的GUI(Graphical User Interface),即图形用户界面。

这里所讲的桌面应用程序,就是具有图形用户界面(GUI)的应用程序。

2. Web应用程序

以前,Mac计算机上几乎只有桌面应用程序。但是,最近形势发生了变化,现在在Web浏览器上可以完成各种各样的工作,不用说网页、地图、歌曲的检索,甚至画流程图、制作表格、编辑文档等原来只能在桌面应用程序中完成的工作,现在在Web浏览器上也能够完成了。

这些都是通过Web浏览器,与Web服务器上运行的软件进行信息交换来实现的。这些在Web服务器上运行的软件也是应用程序,称为Web应用程序。

桌面应用程序在你眼前的Mac计算机上运行,而Web应用程序在远处的Web服务器上运行,如图2-1所示。

图2-1 浏览器与Web应用程序

3. 命令行应用程序

从外观上看,Mac OS X是拥有完美的窗口操作系统,所有工作都可以在图形用户界面中完成。但是这些都根植于Unix系统。

你可以通过称为终端(Teminal)的应用程序一窥究竟(终端软件在【/应用程序/实用工具】目录中)。启动终端软件后,显示如图2-2所示的画面。在这个画面上,通过键盘键入命令,可以控制Mac计算机。

图2-2 终端

在终端上输入的命令也是应用程序的一种,通常被称为命令应用程序,或者命令行应用程序。命令执行时,命令的执行结果以文本的形式显示,与图形用户界面GUI相对应,这些被称CUI(Character User Interface),即字符用户界面。

2.1.2 关于iPhone应用程序

本章前言中已经介绍过本书的目的是学习开发iPhone应用程序的基础知识,那么iPhone应用程序到底是属于什么类型呢?

iPhone应用程序属于桌面应用程序,只不过iPhone应用程序是运行在iOS上的桌面应用程序,iOS是运行于苹果公司推出的手持终端设备(如iPhone,iPad,iTouch)上的操作系统。因此普通Mac桌面应用程序的知识也同样适用于iPhone应用程序。

2.2 框架

2.2.1 简单的【HeIIo WorId】程序

要开发应用程序,首先我们会想到要使用程序开发语言。本书的后面会详细介绍开发Mac应用程序以及iPhone应用程序的程序开发语言——Objective-C 2.0, Objective-C 2.0是从C语言发展而来的。几乎所有介绍程序开发语言的书籍,都会提供一个【Hello World】程序的例子来演示基本的语法。C语言的【Hello World】程序如下。

        #include <stdio.h>

        int main(){
          printf("Hello World!\n");
          return 0;
        }

这就是通常在学习C语言时接触的第一个程序——【Hello World】。这可是一个完整的应用程序,命令行应用程序。在终端上执行时,可以显示字符串【Hello World!】。

不知道你是否注意到,我们要开发的是桌面应用程序,需要显示窗口、菜单。但是,你就是翻烂了介绍C语言的书籍,也不可能找到这方面的内容。

要开发桌面应用程序,掌握了编程语言只是做好一半的准备,还必须了解那些负责生成窗口、菜单的软件,也就是所谓框架(framework)。

2.2.2 框架的出现

在进行桌面应用程序开发时,理论上你是可以使用程序开发语言(如C语言)从头编写出窗口、菜单等GUI部件的,当然这样做需要高超的编程技巧。在现代化的大规模生产(此处使用了制造业的说法,笔者认为软件开发与制造业没有本质的区别)中,是不允许这种低效的生产方式的,于是人们开发出专门提供这些GUI部件的软件包,通常称为库(library)或框架(framework)。库与框架在概念上没有严格的区别,通常认为提供单一功能的软件包为库,提供大的构造功能的软件包为框架。Mac中一般只称呼为框架。

现在你应该可以明白了,框架的出现就是为了提高编程效率,因为人们不满意旧框架的编程效率,才会有各种新的框架出现,以及对旧框架进行的升级活动。根据操作系统或程序开发语言的不同,有各种各样的应用程序开发框架。在Mac中提供的最先进、应用最广泛的框架名为Cocoa。Mac应用程序开发有时也被称为Cocoa应用程序开发。

2.2.3 编程语言与框架的关系

现在在进行应用程序开发时,掌握相应框架方面的知识变得非常关键。应用程序开发的过程,也是有效地运用编程语言来调用框架的功能来实现应用程序设计功能的过程。

那么是不是说,在使用框架前,必须完全得掌握编程语言呢?答案是并非如此,刚开始进行编程时,其实只会用到编程语言中很小的一部分知识。掌握了一定的编程语言知识后,大胆地运用框架的功能,就能完成应用程序的开发。

编程语言与框架对于开发桌面应用程序来说,就像汽车的前后车轮。光掌握了编程语言,是不能进行桌面应用程序的开发的,而框架也是需要语言来调用的,这二者缺一不可,否则汽车就开不起来了。

在使用框架时,要不断加强对编程语言的理解。再经过若干次实践,就能很好地掌握这两个方面了。

2.3 Mac OS X以及iPhone SDK中的框架

2.3.1 框架的安装目录

经过上述的介绍,我们已经了解了开发桌面应用程序是需要框架的,我们需要确认Mac OS X中有些什么框架,以及Mac OS X的框架安装在什么地方。

可以打开Finder工具,在【/系统/资源库/Frameworks】目录中找到安装在Mac OS X中的所有框架文件。框架都是保持在以【.framework】为结尾的文件夹中,如图2-3所示。这其中也包括最重要的框架——Cocoa。

图2-3 框架所在目录

这个目录下的所有内容都是应用程序与操作系统联系的纽带,使用好它们就能更好地利用Mac OS X以及iOS提供的功能了。

2.3.2 Cocoa与Carbon

在2.2节我们知道了Mac OS X中有许多框架。但是,作为桌面应用程序的基础框架只有两种,即Cocoa与Carbon。

为什么会有两种呢?这是有其历史原因的。下面先简单地介绍一下Mac OS系统的发展史。Macintosh产生于1984年,从那时开始,Mac OS经过不断的版本升级,发展到了Mac OS 9版本。但是,这些OS是发展于旧的构架,经常出现宕机的毛病,需要进行根本性的改造。Apple公司采取的策略是,收购了一家名为NeXT的公司,将该公司拥有的名为OPENSTEP(旧名NeXTSTEP)的OS改造成新的Mac OS系统,这就是Mac OS X系统,发布于2001年。

因此,对于Mac OS来讲,到Mac OS 9为止的版本与Mac OS X完全是不同的东西,而Cocoa关于Cocoa这个名称的由来,没有明确的说法。当时正是以咖啡名称命名的Java语言大行其道的时候,于是Cocoa就有了这个以饮料命名的名称,这只是其中的一个传说而已。是随着Mac OS X而推出的新框架。Carbon是为了让以前运行在Mac OS 9系统上的应用程序,能运行在Mac OS X上而开发的框架。

Mac OS X刚推出的时候,使用Carbon框架的应用程序比较多,那是因为Mac OS 9时代的应用程序都是通过使用Carbon改造后运行于Mac OS X上的,而Cocoa应用程序必须从头开始开发,因此在初期几乎没有。

但是Apple公司多次申明Cocoa才是主流的框架,也经过了多次升级改良。最重要的是程序员们意识到了Cocoa压倒性的高效率。因此现在很多以Cocoa为基础开发的应用程序不断涌现,从此只要是开发新的应用程序,第一选择就是Cocoa。

2.3.3 应用程序中使用的框架

应用程序中到底使用的是Carbon,还是Cocoa,Mac系统中提供了调查方法。下面将介绍如何调查应用程序中使用的框架。

在终端中可以使用otool命令来完成此项工作,例如调查Safari中使用了哪些框架时,先启动终端,然后输入如下的命令。

        $ cd /Applications/Safari.app/Contents/MacOS
        $ otool -L Safari

这样屏幕上会显示如下的内容。

        Safari:
          /usr/lib/libsqlite3.dylib (compatibility version 9.0.0, current
    version 9.6.0)
          /System/Library/Frameworks/PubSub.framework/Versions/A/PubSub
    (compatibility version 1.0.0, current version 1.0.0)
          /System/Library/PrivateFrameworks/CrashReporterSupport.framework/
    Versions/A/CrashReporterSupport (compatibility version 1.0.0, current
    version 1.0.0)
          /usr/lib/libxar.1.dylib  (compatibility  version  1.0.0,  current
    version 1.0.0)
          /System/Library/Frameworks/CoreLocation.framework/Versions/A/
    CoreLocation (compatibility version 1.0.0, current version 11.0.0)
          /System/Library/Frameworks/AddressBook.framework/Versions/A/
    AddressBook (compatibility version 1.0.0, current version 862.0.0)
          /System/Library/PrivateFrameworks/Apple80211.framework/Versions/A/
    Apple80211 (compatibility version 1.0.0, current version 2.0.0)
          /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon
    (compatibility version 2.0.0, current version 152.0.0)
          /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa
    (compatibility version 1.0.0, current version 15.0.0)
          /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit

    (compatibility version 1.0.0, current version 275.0.0)
          /System/Library/Frameworks/JavaScriptCore.framework/Versions/A/
    JavaScriptCore (compatibility version 1.0.0, current version 533.17.6)
          /usr/lib/libicucore.A.dylib (compatibility version 1.0.0, current
    version 40.0.0)
          /System/Library/Frameworks/OpenGL.framework/Versions/A/OpenGL
    (compatibility version 1.0.0, current version 1.0.0)
          /System/Library/Frameworks/Quartz.framework/Versions/A/Quartz
    (compatibility version 1.0.0, current version 1.0.0)
          /System/Library/Frameworks/Security.framework/Versions/A/Security
    (compatibility version 1.0.0, current version 36910.0.0)
          /System/Library/Frameworks/SecurityFoundation.framework/Versions/A/
    SecurityFoundation (compatibility version 1.0.0, current version 36840.0.0)
          /System/Library/Frameworks/SecurityInterface.framework/Versions/A/
    SecurityInterface (compatibility version 1.0.0, current version 36981.0.0)
          /System/Library/PrivateFrameworks/SyndicationUI.framework/Versions/
    A/SyndicationUI (compatibility version 1.0.0, current version 1.0.0)
          /System/Library/Frameworks/SystemConfiguration.framework/Versions/
    A/SystemConfiguration  (compatibility  version  1.0.0,  current  version
    289.0.0)
          /System/Library/Frameworks/WebKit.framework/Versions/A/WebKit
    (compatibility version 1.0.0, current version 533.17.8)
          /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current
    version 7.9.0)
          /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current
    version 123.0.0)
          /usr/lib/libobjc.A.dylib  (compatibility  version  1.0.0,  current
    version 227.0.0)
          /System/Library/Frameworks/CoreServices.framework/Versions/A/
    CoreServices (compatibility version 1.0.0, current version 44.0.0)
          /System/Library/Frameworks/CoreFoundation.framework/Versions/A/
    CoreFoundation (compatibility version 150.0.0, current version 550.0.0)
          /System/Library/Frameworks/ApplicationServices.framework/Versions/
    A/ApplicationServices  (compatibility  version  1.0.0,  current  version
    38.0.0)
          /System/Library/Frameworks/Foundation.framework/Versions/C/
    Foundation (compatibility version 300.0.0, current version 751.0.0)
          /System/Library/Frameworks/QuartzCore.framework/Versions/A/
    QuartzCore (compatibility version 1.2.0, current version 1.6.0)

          /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
    (compatibility version 45.0.0, current version 1038.0.0)

这些就是Safari中使用的框架列表。而且还表明了所有框架的路径【/System/Library/Frameworks】,路径后面的即为框架的名称,不仅有Cocoa,还使用很多其他的框架。

在上面的列表中,我们可以发现,Safari中同时存在了Cocoa与Carbon。实际上在Safari中主框架为Cocoa,不足的地方由Carbon来补充。因此Cocoa与Carbon框架并非排他性的框架,关于这些在2.4节会有更详细的说明。

2.4 Cocoa与Carbon的发展轨迹

作为Mac的用户来说,可能你已经听过不少关于Cocoa与Carbon的传言。这其中有正确的地方,也有误解之处,下面就一一解释。

1. Cocoa是面向对象型的框架,所以很难掌握?

Cocoa的确是采用面向对象思想进行设计的框架,面向对象听起来好像很难,那么Cocoa是不是很难掌握呢?

事实并非如此。刚开始使用Cocoa时,并不用完全理解面向对象的概念,掌握几个专门词汇就足够了。

相反,在使用Cocoa的过程中,自然地就理解了面向对象的程序设计思想。可以说Cocoa是所有面向对象的框架中最通俗,也是最优秀的一种框架。因此不用太在意Cocoa是面向对象型的框架。

2. Carbon是用C语言开发的,懂C语言的人应该用Carbon?

Carbon的确是用C语言开发的,而Cocoa是用Objective-C这样冷僻的编程语言开发的,对于大多数人来说,应该更熟悉C语言。

但是,开发桌面应用程序时,除了要学习开发语言外,还必须学习框架的用法。就算你很熟悉C语言,但是你还是要学习Carbon的相关知识。

因此,笔者还是建议你采用更有前途、编程效率更高的Cocoa。同时,如果你已经熟悉了C语言,掌握Objective-C就是很容易的事情。

3. Carbon在将来会消失?

Carbon应该不会消失的。在2.3节已经介绍过了,Cocoa与Carbon并非是对立的。

的确,Cocoa与Carbon是完全不同的框架,各自的设计思想是不一样的,因此就有了哪一个更优秀的讨论。但是它们决非是彼此排他性的框架。从Cocoa中可以调用Carbon,从Carbon中也可以调用Cocoa,彼此有自己的专长。因此一些应用程序经常以Cocoa为主,需要的时候也使用Carbon。与此相反的使用方式也有的。

因此你完全用不着担心Carbon将来会消失。

4. Carbon应用程序使用Cocoa进行改写后速度会提高?

程序运行的速度不一定会提高。首先,程序的运行速度并不仅仅与选择的框架有关,更大程度与如何合理组织代码相关联。如果考虑改变使用的框架,不如在代码的优化上多下一点工夫。

但是,排除代码质量的差异来讲,Cocoa比Carbon更有优势。一个很大的理由就是,在Mac OS X的新技术中,以使用Cocoa为前提的东西更多。如果想积极地导入新技术,Cocoa更有优势。

另外,Carbon框架还在不断地进行整理。因为Carbon的内部设计比较旧,为了在最新的Mac OS X中运行必须要加入不少补丁,很多部分被苹果公司申明为不推荐使用(deprecated),不推荐使用的将来有可能会被舍弃的,应尽量用其他的东西替换它。因此考虑到将来的维护,索性全部采用Cocoa比较好。

5. 如果使用Windows版的Cocoa进行开发,在Windows上也能运行Cocoa应用程序?

到目前为止,只能在Mac OS X上进行Cocoa应用程序开发。苹果公司到底是否提供在Windows上运行Cocoa应用程序的支持,现在还很难说。

假如开发了在Windows上运行的Cocoa及其变换框架,那Cocoa应用程序也能在Windows上运行吗?如果仅仅是使用了Cocoa框架的应用程序我想是可以在Windows上运行的。在2.3节中我们已经了解到了,一个桌面应用程序不仅仅要使用Cocoa,还会使用其他很多的框架。因此,就算有了Windows版的Cocoa,也不意味着所有的Cocoa应用程序都能在Windows上运行。