天天看点

iphone开发笔记三:helloworld运行原理

AppStore掘金——iPhone SDK应用程序开发

这本书的hello讲的不错摘录下来。

3.2.3  史上最无用的应用程序:HelloView

在能够显示"Hello, World!"之前,要先试验做一个更无用的程序"Hello, View!"。除了创建一对窗口和视图之外,这个应用程序不会做任何事。实际上,由于UIView类只是一个基类,它甚至连显示一些文字都做不到。这个应用程序唯一的用处,就是作为iPhone上任何GUI应用程序都要有的第一行代码。

你可以创建一个基于窗口的应用程序项目,命名为HelloView,加入如例3-1、例3-2和例3-3中所示的代码,就能够用SDK编译这个应用程序了。和本章中的大多数例子一样,你可能也希望从项目中去掉Interface Builder,这样就可以了解各个对象是如何在代码中创建出来的。

例3-1  HelloView应用程序代理的原型(HelloViewAppDelegate.h)

  1. #import <UIKit/UIKit.h> 
  2. @interface HelloViewAppDelegate : NSObject  <UIApplicationDelegate> {  
  3.         /* 你的应用程序中的一个窗口,也是唯一的一个 */  
  4.         UIWindow *window;  
  5.         /* 将要在这个窗口中显示的视图类 */  
  6.         UIView *myView;  
  7. }  
  8. @property (nonatomic, retain) IBOutlet UIWindow *window;  
  9. @end 

例3-2  HelloView应用程序代理(HelloViewAppDelegate.m)

  1. #import "HelloViewAppDelegate.h"  
  2. @implementation HelloViewAppDelegate  
  3. @synthesize window;  
  4. - (void)applicationDidFinishLaunching:(UIApplication *)application {  
  5.         CGRect screenBounds = [ [ UIScreen mainScreen ]  applicationFrame ];  
  6.         CGRect windowBounds = screenBounds;  
  7.         windowBounds.origin.y = 0.0;  
  8.         /* 初始化窗口 */  
  9.         self.window = [ [ UIWindow alloc ]  initWithFrame: screenBounds ];  
  10.         /* 初始化视图 */  
  11.         myView = [ [ UIView alloc] initWithFrame:  windowBounds ];  
  12.         /* 将视图链接到窗口 */  
  13.         [ window addSubview: myView ];  
  14.         /* 令窗口成为主窗口并显示出来 */  
  15.         [ window makeKeyAndVisible ];  
  16. }  
  17. - (void)dealloc {  
  18.         [ myView release ];  
  19.         [ window release ];  
  20.         [ super dealloc ];  
  21. }  
  22. @end 

例3-3  HelloView主函数(main.m)

  1. #import <UIKit/UIKit.h> 
  2. int main(int argc, char *argv[]) {  
  3.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];  
  4.         /* 用应用程序代理类的名字作为参数进行调用 */  
  5.     int retVal = UIApplicationMain(argc, argv, nil, @"HelloViewAppDelegate");  
  6.     [pool release];  
  7.     return retVal;  
  8. 3.2.4  行为解释 HelloView应用程序从外表上看起来并没做什么事,但也有其内部驱动机制,其行为如下。 1. 当应用程序启动时,其main函数被调用,正如一个通常的C语言程序一样。这个函数转入Objective-C领域,并将应用程序实例化。然后应用程序通知代理HelloView AppDelegate,该代理是在调用UIApplicationMain时指定的。main函数还负责初始化一个自动回收池。自动回收池被广泛用于苹果公司的Cocoa框架中,来处置那些在创建时就已经指明要进行autorelease的对象。这样做就等于告知应用程序,对于这些对象用完之后就不用管了,它们稍后会被回收。 2. 当应用程序对象初始化完毕之后,底层框架会调用HelloViewAppDelegate类的applicationDidFinishLaunching方法。这就是程序的Objective-C部分开始运转的地方。 3. 系统调用UIScreen类的applicationFrame方法,得到应用程序的显示窗口的坐标与大小。这样就可以创建一个新窗口,让应用程序的主视图可以安置在其中。要记住,你稍后对此进行修改,使用整个屏幕区域,好让你的应用程序能在本质上更先进。 4. 应用程序创建主视图类,使用的显示区域从0 × 0位置(窗口的左上角)开始。然后会将视图设置为窗口的内容。 5. 应用程序代理最终会指示窗口来到前端,并显示自身。这样视图就会显示出来,不过并没有呈现任何内容。 3.2.5  从UIView派生 例子HelloView显示了构建并显示一对窗口-视图所需要的最少代码。UIView类自身仅仅是一个基类,实际上它并不能显示任何内容。要创建一个有实际用途的应用程序,你或者需要将一个功能更丰富的对象附着到UIView上,或者派生一个新的UIView类,在其中加入更多功能。iPhone SDK中有许多UIView类的子类,可以提供不同类型的功能。你也可以创建自己的子类,构建一个自定义视图。 要从UIView派生一个子类,需要编写一个新的接口与实现,来声明该子类。下面的代码片段创建了一个名为MainView的类,作为UIView的一个子类:
    1. @interface MainView : UIView  
    2. {  
    3. }  
    4. - (id)initWithFrame:(CGRect)rect;  
    5. - (void)dealloc;  
    6. @end 
    MainView类继承自UIView类,所以此时它与UIView的功能相同。为了令这个类更有用处,你需要加入新功能。下面的片段就是之前代码的一个新版本,其中加入了一个变量,其中存有一个名为UITextView的文本框类。实际上,你能够轻易地将一个UITextView对象直接附着到窗口上,因为这个类就是派生自UIView的。在这里,你将其集成到自己的定制类中:
    1. #import <UIKit/UITextView.h> 
    2. @interface MainView : UIView  
    3. {  
    4.         UITextView *textView;  
    5. }  
    6. - (id)initWithFrame:(CGRect) rect;  
    7. - (void)dealloc;  
    8. @end 
    你可能已经注意到了上面的两个方法initWithFrame和dealloc。这些方法是默认的初始化与析构方法,并将被你的子类MainView重写,从而扩充UIView类的功能。 提示 各种类使用了一个通用构造方法,名为alloc,但是你不必重写这个方法。你可以将自己的自定义初始化代码放在初始化方法中,比如init和initWithFrame。 如你所见,initWithFrame方法会在视图第一次实例化时被调用,对类做初始化操作。一个边框结构体被传递给它,用来定义显示区域。你应该在这个方法中放入对变量或其他对象做初始化的代码。第二个方法dealloc,则在对象被丢弃时调用。在此,你必须释放你的类中之前分配的所有资源,这样当对象被销毁时这些资源也可以被回收。这两个方法都要调用它们的父类方法,这样才能让UIView类对其自身内部的功能进行处理。 下面给出的,是这两个重要方法的模板:
    1. @implementation MainView  
    2. - (id)initWithFrame:(CGRect)rect {  
    3.         /* 首先调用父类的initWithFrame方法,  
    4.       * 来初始化UIView对象 */  
    5.         self = [ super initWithFrame: rect ];  
    6.         /* 如果对象已经被初始化过了,self指针将会是nil */  
    7.         if (self != nil) {  
    8.             /* 在这里初始化你的类变量 */  
    9.             /* 在这里为你的类分配初始资源 */  
    10.         }  
    11.         return self;  
    12. }  
    13. - (void)dealloc  
    14. {  
    15.         /* 在这里释放你的类的资源 */  
    16.         /* 调用父类的dealloc方法,  
    17.         /* 将UIView持有的资源释放 */  
    18.         [ super dealloc ];  
    19. }  
    20. @end 

继续阅读