3.3 一个简单的例子

知识点讲解光盘:视频\知识点\第3章\一个简单的例子.mp4

在本节的内容中,将首先举一个十分简单的例子,编写一段Objective-C程序,这段简单程序能够在屏幕上显示短语“first Programming!”。整个代码十分简单,下面是完成这个任务的Objective-C程序。

        //显示短语
        #import <Foundation/Foundation.h>
        // 定义main方法,作为程序入口
        int main(int argc, char *argv[])
        {
            @autoreleasepool
            {
                NSLog(@"Hello Objective-C");  // 执行输出
            }
            return 0;  // 返回结果
        }

对于上述程序,我们可以使用Xcode编译并运行程序,或者使用GNU Objective-C编译器在Terminal窗口中编译并运行程序。Objective-C程序最常用的扩展名是“.m”,我们将上述程序保存为“prog1.m”,然后可以使用Xcode打开。

注意:在Objective-C中,小写字母和大写字母是有区别的。Objective-C并不关心程序行从何处开始输入,程序行的任何位置都能输入语句。基于此,我们可以开収容易阅读的程序。

3.3.1 使用Xcode编辑代码

Xcode是一款功能全面的应用程序,通过此工具可以输入、编译、调试并执行Objective-C程序。如果想在Mac上快速开发Objective-C应用程序,则必须学会使用这个强大的工具的方法。在本章前面的章节中,已经介绍了安装并搭建Xcode工具的流程,接下来将简单介绍使用Xcode编辑Objective-C代码的基本方法。

(1)Xcode位于“Developer”文件夹内中的“Applications”子文件夹中,快捷图标如图3-1所示。

图3-1 Xcode图标

(2)启动Xcode,在File菜单下选择New Project命令,如图3-2所示。

图3-2 启动一个新项目

(3)此时出现一个窗口,如图3-3所示。

图3-3 启动一个新项目:选择应用程序类型

(4)单击Create a new Xcode Project后会出现如图3-4所示的窗口。在New Project窗口的左侧,显示了可供选择的模板类别。因为是在计算机中调试,所以选择左侧“OS X”下的Application选项,然后在右侧单击Command Line Tool模板,再单击Next(下一步)按钮。窗口界面效果如图3-4所示。

图3-4 单击Command Line Tool模板

(5)单击Choose按钮打开一个新窗口,如图3-5所示。

图3-5 Xcode文件列表窗口

(6)在此将前面的程序命名,保存在本地机器后,在Xcode中的编辑界面如图3-6所示。

图3-6 Xcode prog1项目窗口

(7)此时可以打开前面创建的第一段Obiective-C代码。不要担心屏幕上为文本显示的各种颜色。Xcode使用不同的颜色指示值、保留字等内容。

现在应该编译并运行第一个程序了,但是首先需要保存程序,方法是从File菜单中选择Save。如果在未保存文件的情况下尝试编译并运行程序,Xcode会询问您是否需要保存。在Build菜单下,可以选择Build或Build and Run。我们选择后者,因为如果构建时不会出现任何错误,则会自动运行此程序。也可单击工具栏中出现的Build and Go图标。

Build and Go意味着“构建,然后执行上次最后完成的操作”,这可能是Run、Debug、Run with Shark或Instruments等。首次对项目使用此图标时,Build and Go意味着构建并运行程序,所以此时使用这个操作没有问题。但是一定要知道“Build and Go”与“Build and Run”之间的区别。

如果程序中有错误,在此步骤期间会看到列出的错误消息。如果情况如此,可回到程序中解决错误问题,然后再次重复此过程。解决程序中的所有错误之后,会出现一个新窗口,其中显示prog1 – Debugger Console。如果该窗口没有自动出现,可迚入主菜单栏并从Run菜单中选择Console,这样就能显示了。

3.3.2 基本元素介绍

1.注释

接下来开始分析文件first.m,程序的第一行。

        //显示短语

上述代码表示一段注释,在程序中使用的注释语句用于说明程序并增强程序的可读性。注释负责告诉该程序的读者,不管是程序员还是其他负责维护该程序的人,这只是程序员在编写特定程序和特定语句序列时的想法。一般首行注释用来描述整个程序的功能。

在Objective-C程序中,有如下两种插入注释的方式。

❑第一种:使用两个连续的斜杠“//”,在双斜杠后直到这行结尾的任何字符都将被编译器忽略。

❑第二种:使用“/*…*/”注释的形式,在中间不能插入任何空格。“/*”表示开始,“*/”表示结束,在两者之间的所有字符都被看作注释语句的一部分,从而被Objective-C编译器忽略。

当注释需要跨越很多程序行时,通常使用这种注释格式,例如下面的代码。

        /*
        这是注释,因为很长很长很长很长很长很长的,
        所以得换行,
        功能是显示一行文本。
        如果不明白可以联系作者:
        xxxx@yahoo.com
        */

在编写程序或者将其键入到计算机上时,应该养成在程序中插入注释的习惯。使用注释有如下两个好处。

(1)当特殊的程序逻辑在您的大脑中出现时就明白程序,要比程序完成后再回来重新思考这个逻辑简单得多。

(2)通过在工作的早期阶段把注释插入程序中,可在调试阶段隔离和调试程序逻辑错误时受益匪浅。注释不仅可以帮助您(或者其他人)通读程序,而且还有助于指出逻辑错误的根源。

2.#import指令

我们继续分析程序,看接下来的代码。

        #import <Foundation/Foundation.h>

#import指令的功能是,告诉编译器找到并处理名为Foundation.h的文件,这是一个系统文件,表示这个文件不是我们创建的。#import表示将该文件的信息导入或包含到程序中,这个功能像把此文件的内容键入到程序中。例如上述代码可以导入文件Foundation.h。

在Objective-C语言中,编译器指令以@符号开始,这个符号经常用在使用类和对象的情况。在下面的表3-1中,对Objective-C语言中的指令迚行了总结。

表3-1 编译器指令

3.主函数

接下来看如下剩余的代码。

            int main (int argc, const char * argv[l)
            {
                  NSAutoreleasePool ' pool =  [ [NSAutoreleasePool alloc]  init] ;
                        NSLog  ( @ "first Programming! " ) ;
                    [pool drain] ;
                return 0;
                    }

上述代码都被包含在函数main()中,此函数和C语言中的同名函数类似,是整个程序的入口函数。上述代码功能是指定程序的名称为main,这是一个特殊的名称,功能是准确地表示程序将要在何处开始执行。在main前面的保留关键字int用于指定main返回值的类型,此处用int表示该值为整型(在本书后面的章节中将更加详细地讨论类型问题)。

在上述main代码块中包含了多条语句。我们可以把程序的所有语句放入到一对花括号中,最简单的情形是:一条语句是一个以分号结束的表达式。系统将把位于花括号中间的所有程序语句看作main例程的组成部分。首先看如下第一条语句。

        NSAutoreleasePool ' pool =  [ [NSAutoreleasePool alloc]  init] ;

上述语句为自动释放池在内存中保留了空间(会在本书后面的“内存管理”章节讨论这方面的内容)。作为模板的一部分,Xcode会将这行内容自动放入程序中。

接下来的一条语句用于指定要调用名为NSLog的例程,传递或传送给NSLog例程的参数或实参是如下字符串。

        @ "first Programming! "

此处的符号@位于一对双引号的字符串前面,这被称为常量NSString对象。NSString例程是Objective-C库中的一个函数,它只能显示或记录其参数。但是之前它会显示该例程的执行日期和时间、程序名以及其他在此不会介绍的数值。在本书的后面的内容中,不会列出NSLog在输出前面插入的这些文本。

在Objective-C中,所有的程序语句必须使用分号“;”结束,这也是为什么分号在NSLog调用的结束圆括号之后立即出现的原因。在退出Objective-C程序之前,应该立即释放已分配的内存池和与程序相关联的对象,例如使用类似于下面的语句可以实现。

        [pool drain];

注意:Xcode会在程序中自动插入此行内容。

在函数main中的最后一条语句是。

        return 0;

上述语句的功能是终止main的运行,并且返回状态值0。在Objective-C程序中规定,0表示程序正常结束。任何非零值通常表示程序出现了一些问题,例如无法找到程序所需要的文件。

如果使用Xcode迚行调试,会在Debug Console窗口中发现在NSLog输出的行后显示下面的提示。

        The Debugger has exited with status 0.

假如修改上面的程序,修改后能够同时显示文本“Objective-C OK”。要想实现这个功能,可以通过简单添加另一个对NSLog例程的调用的方法来实现,例如使用下面的代码实现。

        #import <Foundation/Foundation.h>
            int main (int argc, const char * argv[l)
            {
              .     NSAutoreleasePool ' pool =  [ [NSAutoreleasePool alloc]  init] ;
                      NSLog  ( @ "first Programming! " ) ;
                      NSLog (@" Objective-C OK! ");
                    [pool drain] ;
                return 0;
                  }

在编写上述代码时,必须使用分号结束每个Objective-C程序语句。执行后会输出。

        first Programming!
        Objective-C OK!

而在下面的代码中可以看到,无需为每行输出单独调用NSLog例程。

        #import <Foundation/Foundation.h>
        int main (int argc, const char *argv[])
        {
            NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
            NSLog (@"look...\n..1\n...2\n....3");
            [pool drain];
            return 0;
        }

在上述代码中,首先看看特殊的两字符序列。“\n”中的反斜杠和字母是一个整体,合起来表示换行符。换行符的功能是通知系统要准确完成其名称所暗示的转到一个新行的工作。任何要在换行符之后输出的字符随后将出现在显示器的下一行。其实换行符非常类于HTML标记中的换行标记<br>。执行上述代码后会输出。

        look...
        ..1
        ...2
        ....3

4.显示变量的值

在Objective-C程序中,通过NSLog不仅可以显示简单的短语,而且还能显示定义的变量值并计算结果。例如在下面的代码中,使用NSLog显示了数字“10+20”的结果。

        #import <Foundation/Foundation.h>
        int main (int argc, const char *argv[])
        {
            NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
            int sum;

            sum = 10 + 20;

            NSLog (@"The sum of 10 and 20 is %i", sum);
            [pool drain];
            return 0;
        }

对于上述代码的具体说明如下所示。

(1)函数main会自动释放池后面的第一条程序语句,将变量sum定义为整型。Objective-C程序中,在使用所有程序变量前必须先定义它们。定义变量的目的是告诉Objective-C编译器程序将如何使用这些变量。编译器需要确保这些信息生成正确的指令,便于将值存储到变量中或者从变量中检索值。被定义成int类型的变量只能够存储整型值,例如3、4、-10和0都是整型值,也就是说没有小数位的值是整型值。而带有小数位的数字,例如2.34、2.456和27.0等被称为浮点数,它们都是实数。

(2)整型变量sum的功能是存储整数10和20的和。在编写上述代码时,故意在定义这个变量的下方预留了一个空行,这样做的目的是在视觉上区分例程的变量定义和程序语句(注意:这种做法是一个良好的风格,在很多时候,在程序中添加单个空白行可使程序的可读性更强)。

(3)代码“sum = 10+20;”表示数字10和数字20相加,并把结果存储(如赋值运算符,或者等号所示)到变量sum中。

(4)NSLog语句也调用了圆括号中的两个参数,这些参数用逗号隔开。NSLog语句的第一个参数总是要显示的字符串。然而在显示字符串的同时,通常还希望要显示某些程序变量的值。在上述代码中,希望在显示字符之后还要显示变量sum的值。

        The sum of 50 and 25 is

第一个参数中的百分号是一个特殊字符,它可以被函数NSLog识别。紧跟在百分号后的字符指定在这种情况下将要显示的值类型。在前一个程序中,字母i被NSLog例程识别,它表示将要显示的是一个整数。只要NSLog例程在字符串中发现字符“%i”,它都将自动显示例程第二个参数的值。因为sum是NSLog的下一个参数,所以它的值将在显示字符The sum of 10 and 20 is之后自动显示。

上述代码执行后会输出。

        The sum of 10 and 20 is 30