分类: 系统运维
2011-08-29 11:31:56
1. main.m
这个文件中的主函数main(见代码清单1-1)是整个应用执行的起点。其中第一句建立了一个自动释放池;第二句调用UIApplicationMain函数建立起应用对象(application object)和事件循环(event cycle),事实上这个函数永远不会返回,因为它将一直运行,直到用户按下Home按钮为止;第三句释放了前面建立起来的自动释放池,同时也会释放池中的所有变量,这严格执行了内存管理机制。
代码清单1-1 Main函数
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
作为iPad开发者,不需要修改这个主文件,但是为了帮助你更好地理解程序执行的流程,下面简单介绍程序进入UIApplicationMain函数后如何找到其他文件的入口。
值得注意的是,UIApplicationMain函数的第三个参数指定了该应用从哪个类初始化,它的值为nil,因此程序会默认通过UIApplication来初始化应用对象。UIApplicationMain函数的第四个参数指定了应用的代理从哪个类初始化,它的值为nil,因此程序会默认在HelloWorldMail-Info.plist文件中寻找一个叫做“Main nib file base name”的项,打开这个.plist文件,会发现这个键值为“MainWindow”,因此程序会从MainWindow.xib文件中去寻找应用的代理所属的类。
小知识:对象(object)
Objective-C是面向对象的编程语言,因此对象也是该语言的核心内容。对象中包括了一些相关数据,这些是其成员变量(member variable或者instance variable),除非特别做出声明,否则这些变量只有其所属对象能够操作(读、写、复制等)。对象也提供了一些操作成员变量的方法(method),类似于C++中的函数(function)。
在Objective-C中,永远只需要通过一个对象的指针来操作该对象。空指针是一个特殊的指针,用nil表示(类似于C++中的NULL)。
小知识:消息机制(messaging)
可以给任何一个对象传递一个消息,告诉它去执行某个方法,这个操作叫做消息机制,类似于C++中的函数调用。消息传递的格式为:
[receiver message]
其中receiver为一个对象,而message在源代码中就是一个方法的名称和相应的参数。例如:
[NSAutoreleasePool alloc]
NSAutoreleasePool是一个类,定义了一个自动释放库,在这里就是receiver。alloc是一个方法,在这里就是message。
2. HelloWorldMail-Info.plist
plist指的是属性列表(Property List),包含以XML格式组织起来的数据,每一个数据都有其自己的命名。通常情况下不需要修改plist文件,但有例外,比如想在iPhone上隐藏状态条或指定应用的图标文件。
3. HelloWorldMailAppDelegate.h和HelloWorldMailViewController.h
这是两个头文件。以HelloWorldMailAppDelegate.h为例(见代码清单1-2)来简单看一下Objective-C的头文件结构。在学习过程中,可以将Objective-C和C++的语法做出类比,以辅助记忆。
代码清单1-2 HelloWorldMailViewController.h
#import
@class HelloWorldMailViewController;
@interface HelloWorldMailAppDelegate : NSObject
UIWindow *window;
HelloWorldMailViewController *viewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet HelloWorldMailViewController *viewController;
@end
第一句#import,是用于包含头文件的语句,类似于C++中的#include。紧随其后,系统文件往往用<>括号括起来,而自己写的文件用""引起来。
第二句@class,是一个指令语句,作用是对一个类做出前向声明,能最小化编译器和连接器所看到的代码的数量。这类似于C++中的前向声明指令class。
从@interface到@end之间,是类的声明。HelloWorldMailAppDelegate是类的名称,而冒号后面的NSObject是其父类名称。
HelloWorldMailAppDelegate类有两个成员变量,是两个指针,指针所指向的对象分别属于UIWindow类和HelloWorldMailViewController类。UIWindow是一个窗口类,绝大部分的应用都会用到这个类。HelloWorldMailViewController则是在另一个头文件HelloWorldMailViewController.h中定义的一个类。需要注意的是,在Objective-C中,只使用对象的指针,而不是对象本身。这一点可以从这两个成员变量的定义中看出。
再往下面,@property为两个成员变量提供了属性,使得我们可以通过点语法(dot syntax)来对这两个成员变量进行读写操作(access)。关于这一点,在后面还会做出详细说明。
4. HelloWorldMailAppDelegate.m和HelloWorldMailViewController.m
这两个文件包含了类的实现。以HelloWorldMailAppDelegate.m为例(见代码清单1-3)来简单说明其中语法和功能。
代码清单1-3 HelloWorldMailAppDelegate.m
#import "HelloWorldMailAppDelegate.h"
#import "HelloWorldMailViewController.h"
@implementation HelloWorldMailAppDelegate
@synthesize window;
@synthesize viewController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
// 这个方法通常是这个应用的编程起点
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
/*
当有来电或短消息时,应用进入Inactive状态
在这个方法中,通常停止计时器、降低OpenGL ES的帧率、暂停游戏
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
/*
重新启动所有暂停了的任务
*/
}
- (void)applicationWillTerminate:(UIApplication *)application {
/*
应用即将彻底结束,所谓彻底结束,是和进入后台相对应的
*/
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
应用收到内存警告时,应当尽量多地释放内存,以缓解内存紧张状况
*/
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
两个#import用于包含头文件。前面提过了,包含非系统性头文件用""引起来。
在@implementation和@end之间,是对HelloWorldMailAppDelegate类的实现。其中@synthesize和头文件中的@property成对出现。#pragma mark只是用于分隔源代码的,不对代码运行产生影响。下面来看一看每一个方法(类似于C++中的函数)的作用。
小知识:Objective-C中的方法(Method)
以HelloWorldMailAppDelegate.m的第一个方法为例。
-(BOOL)application:(UIApplicaiton*)application
didFinishLaunchingWithOptions: (NSDictionary*)launchOptions
其中application和didFinishLaunchingWithOptions是这个方法的签名(signature),application和launchOptions是这个方法的参数,这两个参数的类型分别为UIApplication*和NSDicitonary*。
可以看出,Objective-C方法的签名和参数可以交互出现,一个签名后面跟随一个参数(在C++中,函数的参数都在括号之中,和函数名是分开的)。Objective-C中这样做的好处是,每个参数的类型和意义非常明确,代码可读性很强。
方法开头的(BOOL)表示这个方法的返回值是BOOL类型的。方法开头的减号(-)表明这是一个实例方法(instance method),意思是这个方法的调用者必须是一个类的实例(instance),而不能是一个类(class)本身。相反地,方法开头如果有加号(+),则表明这是一个类方法(class method),意思是这个方法的调用者必须是一个类。
第一个方法的签名为application: didFinishLaunchingWithOptions:,在应用启动后自动被调用。第二个方法的签名为applicationWillResignActive:,在应用即将从活动状态转入非活动状态时被调用。第三个方法的签名为applicationDidBecomeActive:,在应用刚刚转入活动状态后被调用。第四个方法的签名为applicationWillTerminate:,在应用即将退出时被调用。第五个方法的签名为applicationDidReceiveMemoryWarning:,在应用得到内存警告后被调用。以上5个方法都是代理方法(delegate method)。需要注意的是第一个方法中的
[window addSubview:viewController.view];
这一句的作用就是将viewController的视图作为子视图加在window上面。程序启动后,用户所看到的也是viewController.view。因此,如果要修改呈献给用户的内容,就需要修改viewController所属的类HelloWorldMailViewController。
小知识:代理(Delegation)与协议(Protocol)
代理是iPhone开发中一个很重要的设计模式。简单地说,在代理模式中,一个对象(在例子当中就是UIApplication)给其代理(HelloWorldMailAppDelegate的实例)发送消息,向它要求输入或者通知它一个事件即将或者刚刚发生。代理模式的好处是,即使HelloWorldMailAppDelegate不继承UIApplication,它依然可以使用UIApplication的一些方法。在C++中,继承(Inheritance)是重复利用代码的主要方法;而代理则提供了另一种方法,很多时候会比继承更方便。
由于人们希望一些方法能够经常为代理所使用,于是将这些方法合在一块,组成协议。HelloWorldMailAppDelegate采用(Adopt)了UIApplication协议,也就是说它能够执行UIApplication的一些代理方法。
最后一个方法的签名是dealloc。这个方法继承自NSObject类。它非常重要,只有正确地实现它才能够确保无内存泄露。在dealloc中,需要释放所有为HelloWorldMailAppDelegate所拥有的对象。
5. HelloWorldMailViewController.xib和MainWindow.xib
xib文件中包含了视图的信息。如果双击一个xib文件,就会启动IB,可以进行“所见即所得”的操作。
6. HelloWorldMail_Prefix.pch
这是一个包含文件,会和其他文件分开编译,因此不需要在其他文件之中包含它。
7. UIKit.framework, Foundation.framework和CoreGraphics.framework
这是三个最常用的框架(framework),类似于C++中的库(library)。
8. HelloWorldMail.app
这就是在iPhone上的可执行文件了!
1.6.3 添加按钮
这一小节中,我们要让用户能够在应用启动后,看到一个按钮,上面写着“Say Hello World through Mail!”。上一节中提到了,我们需要修改HelloWorldMailViewController这个类,包括其xib文件、h文件和mm文件。为了达成这一目标,需要修改界面文件、修改源文件以及给两者建立起连接。
我们先来修改xib文件。双击HelloWorldMailViewController.xib文件,能看到IB启动,并且呈现出一个大大的白色视图—这就是用户在程序启动后将看到的视图。下面请选择Interface Builder→Tools→Library,将看到一个包含大量界面元素的库(如图1-6所示)—将从这里开始熟悉可用于装饰界面并呈现信息的元素。请找到一个叫做Round Rect Button的按钮元素,将其拖到视图中央。双击这个按钮,可以输入这个按钮上将要显示的文字;本程序中输入的是“Say Hello World through Mail!”(如图1-7所示)。
此时,可以单击工具条中的Build and Run按钮,查看含有按钮的iPad界面,如图1-8所示。这时的按钮还不具备任何功能,因此下面我们所要做的是为按钮添加一点功能—当单击时在调试区域显示“Hello World!”。我们通过修改源文件来添加一个在调试区域显示字符串的方法。请打开HelloWorldMailViewController.h,在@end前面加入以下方法声明:
-(IBAction) didClickButton;
然后打开HelloWorldMailViewController.m,为我们刚刚声明的方法添加实现:
-(IBAction) didClickButton {
NSLog(@"Hello World!");
}
NSLog是做开发调试的最好伙伴,可以用它在程序运行时显示想查看的参数内容,也可以用它来检测代码流程。上面这句的参数@"Hello World!"是要显示的字符串。
至此,我们在xib文件中添加了按钮,也在源文件中添加了按钮按下后要实现的方法,但两者之间的连接尚未建立—这个很简单,请打开HelloWorldMailViewController.xib文件,按住Control键不要松开,同时将鼠标从视图上的按钮拖向File誷 Owner。这时可以看到一个弹出框,如图1-8所示。单击didClickButton,这样连接就建立好了。
此时,请再次单击Build and Run按钮,运行iPad模拟器。按下界面上的按钮,看看调试区域是否显示出了“Hello World!”,如果显示出来了,那么按钮已经具备了基本功能。但只和自己说Hello World是不够的,我们将在下一小节讲解怎么使用邮件编辑器,向全世界任何一个在使用互联网的人说Hello World!
1.6.4 邮件编辑器
使用邮件编辑器,需要完成以下步骤:添加框架(framework),包含头文件,设置代理,完成代理方法。本小节将讲解如何一步一步完成这些工作。当今后学习如何播放音乐、视频,如何调用系统图片库时,将需要完成同样的步骤。
首先,你需要向工程中添加框架MessageUI.framework。在工程文件浏览区域,找到Frameworks组,右键单击后,选择Add→Existing Frameworks,然后在弹出框中选中MessageUI.framework。
接下来,打开HelloWorldMailViewController.h文件,用下面这句来包含所必需的头文件:
#import
#import
#import
@interface HelloWorldMailViewController : UIViewController
}
-(IBAction) didClickButton;
@end
最后打开HelloWorldMailViewController.m,如代码清单1-4所示的修改didClickButton方法,并添加签名为mailComposeController: didFinishWithResult: error:的代理方法。在didClickButton中,我们首先通过[MFMailComposeViewController canSendMail]判断设备的邮件发送功能是否已经设置好。如果设置好了,我们就初始化一个MFMailComposeViewController的实例picker,并且将其代理设置为self—也就是这个消息的接收对象。接下来,我们用setSubject:和setMessageBody: isHTML:两个方法来预设邮件编辑器的主题和正文。此时,邮件编辑器已经设置好了,我们用presentModalViewController: animated:方法来显示邮件接收器。最后,由于我们使用了alloc来创建picker,并且它已经呈现在屏幕上了,因此我们需要release掉。再看看这个代理方法,它在用户发送完邮件或者点击cancel(取消)按钮后被触发。这时,我们需要移除掉picker,方法是dismissModalViewControllerAnimated:。
代码清单1-4 HelloWorldMailViewController.m中两个需要修改的方法
-(IBAction) didClickButton {
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController *picker = [[MFMailComposeViewController alloc] init];
picker.mailComposeDelegate = self;
[picker setSubject:@"Hello World from my iPad app!"];
NSString *emailBody = @"Hey,
\
this is from my first iPad app!";
[picker setMessageBody:emailBody isHTML:YES];
[self presentModalViewController:picker animated:YES];
[picker release];
}
}
- (void)mailComposeController:(MFMailComposeViewController*)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError*)error {
[self dismissModalViewControllerAnimated:YES];
}
此时,再运行iPad应用,你可以打开邮件编辑器了(如图1-9所示)。你可以试着用这款应用给朋友发送邮件,看看他们能不能收到你的问候呢?
图1-2 XCode IDE的界面
1.6.2 工程概览
在左侧工程文件浏览区,可以看到如图1-5所示的内容,下面一一解释这些文件的用途。 如果是首次接触Objective-C,那么这一小节内容至关重要,在这一小节,我们会介绍很多Objective-C编程的基本概念和方法。
1. main.m
这个文件中的主函数main(见代码清单1-1)是整个应用执行的起点。其中第一句建立了一个自动释放池;第二句调用UIApplicationMain函数建立起应用对象(application object)和事件循环(event cycle),事实上这个函数永远不会返回,因为它将一直运行,直到用户按下Home按钮为止;第三句释放了前面建立起来的自动释放池,同时也会释放池中的所有变量,这严格执行了内存管理机制。
代码清单1-1 Main函数
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
作为iPad开发者,不需要修改这个主文件,但是为了帮助你更好地理解程序执行的流程,下面简单介绍程序进入UIApplicationMain函数后如何找到其他文件的入口。
值得注意的是,UIApplicationMain函数的第三个参数指定了该应用从哪个类初始化,它的值为nil,因此程序会默认通过UIApplication来初始化应用对象。UIApplicationMain函数的第四个参数指定了应用的代理从哪个类初始化,它的值为nil,因此程序会默认在HelloWorldMail-Info.plist文件中寻找一个叫做“Main nib file base name”的项,打开这个.plist文件,会发现这个键值为“MainWindow”,因此程序会从MainWindow.xib文件中去寻找应用的代理所属的类。
小知识:对象(object)
Objective-C是面向对象的编程语言,因此对象也是该语言的核心内容。对象中包括了一些相关数据,这些是其成员变量(member variable或者instance variable),除非特别做出声明,否则这些变量只有其所属对象能够操作(读、写、复制等)。对象也提供了一些操作成员变量的方法(method),类似于C++中的函数(function)。
在Objective-C中,永远只需要通过一个对象的指针来操作该对象。空指针是一个特殊的指针,用nil表示(类似于C++中的NULL)。
小知识:消息机制(messaging)
可以给任何一个对象传递一个消息,告诉它去执行某个方法,这个操作叫做消息机制,类似于C++中的函数调用。消息传递的格式为:
[receiver message]
其中receiver为一个对象,而message在源代码中就是一个方法的名称和相应的参数。例如:
[NSAutoreleasePool alloc]
NSAutoreleasePool是一个类,定义了一个自动释放库,在这里就是receiver。alloc是一个方法,在这里就是message。
2. HelloWorldMail-Info.plist
plist指的是属性列表(Property List),包含以XML格式组织起来的数据,每一个数据都有其自己的命名。通常情况下不需要修改plist文件,但有例外,比如想在iPhone上隐藏状态条或指定应用的图标文件。
3. HelloWorldMailAppDelegate.h和HelloWorldMailViewController.h
这是两个头文件。以HelloWorldMailAppDelegate.h为例(见代码清单1-2)来简单看一下Objective-C的头文件结构。在学习过程中,可以将Objective-C和C++的语法做出类比,以辅助记忆。
代码清单1-2 HelloWorldMailViewController.h
#import
@class HelloWorldMailViewController;
@interface HelloWorldMailAppDelegate : NSObject
UIWindow *window;
HelloWorldMailViewController *viewController;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet HelloWorldMailViewController *viewController;
@end
第二句@class,是一个指令语句,作用是对一个类做出前向声明,能最小化编译器和连接器所看到的代码的数量。这类似于C++中的前向声明指令class。
从@interface到@end之间,是类的声明。HelloWorldMailAppDelegate是类的名称,而冒号后面的NSObject是其父类名称。
HelloWorldMailAppDelegate类有两个成员变量,是两个指针,指针所指向的对象分别属于UIWindow类和HelloWorldMailViewController类。UIWindow是一个窗口类,绝大部分的应用都会用到这个类。HelloWorldMailViewController则是在另一个头文件HelloWorldMailViewController.h中定义的一个类。需要注意的是,在Objective-C中,只使用对象的指针,而不是对象本身。这一点可以从这两个成员变量的定义中看出。
再往下面,@property为两个成员变量提供了属性,使得我们可以通过点语法(dot syntax)来对这两个成员变量进行读写操作(access)。关于这一点,在后面还会做出详细说明。
4. HelloWorldMailAppDelegate.m和HelloWorldMailViewController.m
这两个文件包含了类的实现。以HelloWorldMailAppDelegate.m为例(见代码清单1-3)来简单说明其中语法和功能。
代码清单1-3 HelloWorldMailAppDelegate.m
#import "HelloWorldMailAppDelegate.h"
#import "HelloWorldMailViewController.h"
@implementation HelloWorldMailAppDelegate
@synthesize window;
@synthesize viewController;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
// 这个方法通常是这个应用的编程起点
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application {
/*
当有来电或短消息时,应用进入Inactive状态
在这个方法中,通常停止计时器、降低OpenGL ES的帧率、暂停游戏
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
/*
重新启动所有暂停了的任务
*/
}
- (void)applicationWillTerminate:(UIApplication *)application {
/*
应用即将彻底结束,所谓彻底结束,是和进入后台相对应的
*/
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
应用收到内存警告时,应当尽量多地释放内存,以缓解内存紧张状况
*/
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
@end
两个#import用于包含头文件。前面提过了,包含非系统性头文件用""引起来。
在@implementation和@end之间,是对HelloWorldMailAppDelegate类的实现。其中@synthesize和头文件中的@property成对出现。#pragma mark只是用于分隔源代码的,不对代码运行产生影响。下面来看一看每一个方法(类似于C++中的函数)的作用。
小知识:Objective-C中的方法(Method)
以HelloWorldMailAppDelegate.m的第一个方法为例。
-(BOOL)application:(UIApplicaiton*)application
didFinishLaunchingWithOptions: (NSDictionary*)launchOptions
其中application和didFinishLaunchingWithOptions是这个方法的签名(signature),application和launchOptions是这个方法的参数,这两个参数的类型分别为UIApplication*和NSDicitonary*。
可以看出,Objective-C方法的签名和参数可以交互出现,一个签名后面跟随一个参数(在C++中,函数的参数都在括号之中,和函数名是分开的)。Objective-C中这样做的好处是,每个参数的类型和意义非常明确,代码可读性很强。
方法开头的(BOOL)表示这个方法的返回值是BOOL类型的。方法开头的减号(-)表明这是一个实例方法(instance method),意思是这个方法的调用者必须是一个类的实例(instance),而不能是一个类(class)本身。相反地,方法开头如果有加号(+),则表明这是一个类方法(class method),意思是这个方法的调用者必须是一个类。
第一个方法的签名为application: didFinishLaunchingWithOptions:,在应用启动后自动被调用。第二个方法的签名为applicationWillResignActive:,在应用即将从活动状态转入非活动状态时被调用。第三个方法的签名为applicationDidBecomeActive:,在应用刚刚转入活动状态后被调用。第四个方法的签名为applicationWillTerminate:,在应用即将退出时被调用。第五个方法的签名为applicationDidReceiveMemoryWarning:,在应用得到内存警告后被调用。以上5个方法都是代理方法(delegate method)。需要注意的是第一个方法中的
[window addSubview:viewController.view];
这一句的作用就是将viewController的视图作为子视图加在window上面。程序启动后,用户所看到的也是viewController.view。因此,如果要修改呈献给用户的内容,就需要修改viewController所属的类HelloWorldMailViewController。
小知识:代理(Delegation)与协议(Protocol)
代理是iPhone开发中一个很重要的设计模式。简单地说,在代理模式中,一个对象(在例子当中就是UIApplication)给其代理(HelloWorldMailAppDelegate的实例)发送消息,向它要求输入或者通知它一个事件即将或者刚刚发生。代理模式的好处是,即使HelloWorldMailAppDelegate不继承UIApplication,它依然可以使用UIApplication的一些方法。在C++中,继承(Inheritance)是重复利用代码的主要方法;而代理则提供了另一种方法,很多时候会比继承更方便。
由于人们希望一些方法能够经常为代理所使用,于是将这些方法合在一块,组成协议。HelloWorldMailAppDelegate采用(Adopt)了UIApplication协议,也就是说它能够执行UIApplication的一些代理方法。
最后一个方法的签名是dealloc。这个方法继承自NSObject类。它非常重要,只有正确地实现它才能够确保无内存泄露。在dealloc中,需要释放所有为HelloWorldMailAppDelegate所拥有的对象。
5. HelloWorldMailViewController.xib和MainWindow.xib
xib文件中包含了视图的信息。如果双击一个xib文件,就会启动IB,可以进行“所见即所得”的操作。
6. HelloWorldMail_Prefix.pch
这是一个包含文件,会和其他文件分开编译,因此不需要在其他文件之中包含它。
7. UIKit.framework, Foundation.framework和CoreGraphics.framework
这是三个最常用的框架(framework),类似于C++中的库(library)。
8. HelloWorldMail.app
这就是在iPhone上的可执行文件了!
1.6.3 添加按钮
这一小节中,我们要让用户能够在应用启动后,看到一个按钮,上面写着“Say Hello World through Mail!”。上一节中提到了,我们需要修改HelloWorldMailViewController这个类,包括其xib文件、h文件和mm文件。为了达成这一目标,需要修改界面文件、修改源文件以及给两者建立起连接。
我们先来修改xib文件。双击HelloWorldMailViewController.xib文件,能看到IB启动,并且呈现出一个大大的白色视图—这就是用户在程序启动后将看到的视图。下面请选择Interface Builder→Tools→Library,将看到一个包含大量界面元素的库(如图1-6所示)—将从这里开始熟悉可用于装饰界面并呈现信息的元素。请找到一个叫做Round Rect Button的按钮元素,将其拖到视图中央。双击这个按钮,可以输入这个按钮上将要显示的文字;本程序中输入的是“Say Hello World through Mail!”(如图1-7所示)。
此时,可以单击工具条中的Build and Run按钮,查看含有按钮的iPad界面,如图1-8所示。这时的按钮还不具备任何功能,因此下面我们所要做的是为按钮添加一点功能—当单击时在调试区域显示“Hello World!”。我们通过修改源文件来添加一个在调试区域显示字符串的方法。请打开HelloWorldMailViewController.h,在@end前面加入以下方法声明:
-(IBAction) didClickButton;
然后打开HelloWorldMailViewController.m,为我们刚刚声明的方法添加实现:
-(IBAction) didClickButton {
NSLog(@"Hello World!");
}
NSLog是做开发调试的最好伙伴,可以用它在程序运行时显示想查看的参数内容,也可以用它来检测代码流程。上面这句的参数@"Hello World!"是要显示的字符串。
至此,我们在xib文件中添加了按钮,也在源文件中添加了按钮按下后要实现的方法,但两者之间的连接尚未建立—这个很简单,请打开HelloWorldMailViewController.xib文件,按住Control键不要松开,同时将鼠标从视图上的按钮拖向File誷 Owner。这时可以看到一个弹出框,如图1-8所示。单击didClickButton,这样连接就建立好了。
此时,请再次单击Build and Run按钮,运行iPad模拟器。按下界面上的按钮,看看调试区域是否显示出了“Hello World!”,如果显示出来了,那么按钮已经具备了基本功能。但只和自己说Hello World是不够的,我们将在下一小节讲解怎么使用邮件编辑器,向全世界任何一个在使用互联网的人说Hello World!
1.7 小结
在这一章中,我们简要地介绍了iPad性能,并与电脑和iPhone做了比较,以强调其主要特性:高分辨率的屏幕、触摸式交互以及不错的移动性能。通过这些比较,我们为iPad应用的设计提供了建议。接下来,我们谈到了iPad开发所必需的知识(Objective-C和Cocoa)和工具(XCode IDE)。最后,我们通过一个邮件编辑器实例,来帮助完成你的第一个iPad应用。在例子当中,我们介绍了最基本的Objective-C语法以及XCode IDE使用方法。有了这一章的基础,你可以开始学习更多的iPad开发技术了!