UIApplication详解

一. UIApplication

(原文找不到出处了,写的不错,向原作者致敬!)

常规iPhone程序对象结构如下:对象个数        对象类型
       UIApplication
           UIApplicationDelegate/subclass
1,N                    UIViewController/subclass
1,N                                    UIView/subclsss

尽管有些书上说可以绕过UIViewController直接对UIView进行操作,但个人认为此层的作用用于管理视图和视图关系

下面分别对上述层次关系的对象类型进行学习。说明下,下面学习的东西仅和问题有关,不会全面学习类中的各种方法和属性。

UIApplication

继承于UIResponder:NSObject

框架:UIKit.framework

头文件:UIApplication.h

每一个应用程序都有一个UIApplication或其子类型的实例。当程序被加载,函数方法UIApplicationMain就被调用执行,它创建了单件模式的UIApplication对象。之后你可以通过执行sharedApplication类方法来访问。

看看main函数
 
  
int  main( int  argc,  char  * argv[]){NSAutoreleasePool  * pool  =  [[NSAutoreleasePool alloc] init]; int  retVal  =  UIApplicationMain(argc, argv, nil, nil);[pool release]; return  retVal;}
可以看出,main函数的作用在于调用UIApplicationMain方法来创建一个UIApplication对象实例,同时也管理了此类的实例的内存释放。那么获取UIApplication对象实例,代码如下: 假设UIApplicationDelegate协议继承类XXXXAppDelegate UIApplication *app = [UIApplication sharedApplication]; XXXXAppDelegate *d = (XXXXAppDelegate *)app.delegate;//Test these code ,it is ok;在main函数中创建了UIApplication实例,同时也就绑定了XXXXAppDelegate看看原型       
int UIApplicationMain ( int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName );    
This function is called in the main entry point to create the application object and the application delegate and set up the event cycle.    argc: The count of arguments in argv; this usually is the corresponding parameter to main.    argv: A variable list of arguments; this usually is the corresponding parameter to main.    principalClassName: The name of the UIApplicationclass or subclass.    delegateClassName: The name of the class from which the application delegate is instantiated.
UIApplication部分: 
UIApplicationMain
->    UIApplication    UIApplicationDelegate实现类
UIApplication->    sharedApplication类方法获取当前程序的UIApplication实例    delegate属性获取UIApplicationDelegate实现类的实例    windows属性获取当前程序涉及到窗口类数组    keyWindow属性获取当前程序关键窗口即然有了UIApplicationDelegate协议的实现类,那如何实现UIViewController/subclass的初始化?实现Controller类的初始化的地方有两处:application:didFinishLaunchingWithOptions:applicationDidFinishLaunching:这两个方法,后者是前期版本下的。在iOS3.0以及之后,应该使用前者来完成开始这个过程。XCode4运行的是application:didFinishLaunchingWithOptions:当然,你也可以删除application:didFinishLaunchingWithOptions:,自己添加applicationDidFinishLaunching方法来实现。不推荐此操作。看下实际对UIApplicationDelegate如何编写其实现类
 
    
#import  < UIKit / UIKit.h >

@class  NavSmallPhoneViewController;

@interface  NavSmallPhoneAppDelegate : NSObject  < UIApplicationDelegate >  {

}

@property (nonatomic, retain) IBOutlet UIWindow
  * window;

@property (nonatomic, retain) IBOutlet NavSmallPhoneViewController
  * viewController;
@end


 
    
#import  " NavSmallPhoneAppDelegate.h "

#import  " NavSmallPhoneViewController.h "

@implementation  NavSmallPhoneAppDelegate


@synthesize  window = _window;

@synthesize  viewController = _viewController;

@synthesize  info;

-  (BOOL)application:(UIApplication  * )application didFinishLaunchingWithOptions:(NSDictionary * )launchOptions
{
//  Override point for customization after application launch.

self.window.rootViewController
  =  self.viewController;
[self.window makeKeyAndVisible];

// Todo 这部分代码是未测试和说明一个问题的:当前UIApplicationDelegate实现类中的window属性来源哪?
UIWindow  * w  =  [UIApplication sharedApplication].keyWindow;
NSLog(
@" %@\n%@ "  ,w ,self.window);
if  (w  ==  self.window)
NSLog(
@" AppDelegate 'window is UIApplication current keyWindow! " );

return  YES;
}



-  ( void )dealloc
{
[_window release];
[_viewController release];
[super dealloc];
}

@end


看头文件,你发现实现类,有了两个属性,window和viewController;就是保存当前实现类所关联的window和视图控制器
通过运行,输出“AppDelegate 'window is UIApplication current keyWindow!”,说明实现类的window属性来源UIApplication实例当前的keyWindow属性。
也就是说,如果UIApplication实例只有一份UIWindow实例,那肯定和其UIApplicationDelegate实现类的window属性指向同一UIWindow实例。

之所以在UIApplicationDelegate实现类定义这么两个属性,就是为了更方便的使用UIWindow和UIViewController,作用就是建立对象树状关系,便于彼此调用和实现。

在这里,应该清楚了UIApplication和UIViewController之间是通过UIWinodw来关联的,尽管在UIApplicationDelegate实现类中定义一个viewController属性。修改下上面的关系图:
常规iPhone程序对象结构如下:
对象个数        对象类型
       UIApplication
           UIApplicationDelegate/subclass
                       UIWindow
                         .rootViewController属性
1,N                                    UIViewController/subclass
1,N                                                    UIView/subclsss

根据现在的对象结构图,可以知道UIWindow实例在此仅仅是起承上启下的作用。
UIWindow继承UIView:UIResponder:NSObject
(

The UIWindow class defines an object known as a window that manages and coordinates the views an app displays on a device screen. Unless an app can display content on an external device screen, an app has only one window.

The two principal functions of a window are to provide an area for displaying its views and to distribute events to the views. To change the content your app displays, you can change the window’s root view; you don’t create a new window. A window belongs to a level—typically, UIWindowLevelNormal—that represents where it sits on the z-axis relative to other windows. For example, a system alert window appears above normal app windows.

Note: When you use storyboards and the Xcode app templates to create an app, a window is created for you. If you choose to create a window in Interface Builder, be sure to select the Full Screen at Launch option in the Attributes inspector so that the window is sized appropriately for the current device. Because a window doesn’t receive touch events outside of its bounds and views aren’t clipped to the window’s bounds by default, an improperly sized window might not be able to deliver touch events to all its views.


)
现在可以看下UIViewController
继承UIResponder:NSObject

UIViewController其子类UINavigationController和UITabBarController为复杂视图控制器和视图的层次结构提供额外的行为处理功能。

针对问题看下,有哪些视图控制器可访问?
  parentViewController  property
  searchDisplayController  property
  splitViewController  property
  modalViewController  property
  navigationController  property
  tabBarController  property
  
  上述控制器访问器都是只读,说明这些控制器是由内部或初始化就进行处理。
  从这里来看,至少可以说明一点,Controller之间的关联是存在的~~
  

最关键,怎么去管理视图?
属性view和方法loadView

UIView又如何得到它的操作者?又如何管理自身的子视图?
继承于UIResponder:NSObject

如果UIView包含在UIViewController下,只能顺起获取到对应的UIView,暂时未知如何根据UIView获取UIViewController

UIView关于管理视图层次,如下:
Managing the View Hierarchy

      superview  property
      subviews  property
      window  property
    – addSubview:
    – bringSubviewToFront:
    – sendSubviewToBack:
    – removeFromSuperview
    – insertSubview:atIndex:
    – insertSubview:aboveSubview:
    – insertSubview:belowSubview:
    – exchangeSubviewAtIndex:withSubviewAtIndex:
    – isDescendantOfView:
    
感觉可以通过属性window来获取Controller,从某一个角度来说,这个Controller应该是当前视图的父对象

=======================================================================================================
UIView.window属性来源于当前UIApplication.keyWindow
可以通过此属性让UIView间接获取到该视图的UIViewController类

文中涉及红色粗体,是本文的相关答案标记。




二. Application的生命周期

from:http://www.189works.com/article-82333-1.html

建议参考:http://blog.csdn.net/kesalin/article/details/6691766 (有很详细的流程图)
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
  2. {
  3. // Override point for customization after application launch.
  4. NSLog(@"程序开始");
  5. return YES;
  6. }
  7.  
  8. - (void)applicationWillResignActive:(UIApplication *)application
  9. {
  10. // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
  11. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
  12. NSLog(@"程序暂停");
  13. }
  14.  
  15. - (void)applicationDidEnterBackground:(UIApplication *)application
  16. {
  17. // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
  18. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
  19. NSLog(@"程序进入后台");
  20. }
  21.  
  22. - (void)applicationWillEnterForeground:(UIApplication *)application
  23. {
  24. // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
  25. NSLog(@"程序进入前台");
  26. }
  27.  
  28. - (void)applicationDidBecomeActive:(UIApplication *)application
  29. {
  30. // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
  31. NSLog(@"程序再次激活");
  32. }
  33.  
  34. - (void)applicationWillTerminate:(UIApplication *)application
  35. {
  36. // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
  37. NSLog(@"程序意外终止");
  38. }

 

实验结果:

1.首次启动应用程序:

2012-06-26 11:06:39.313 WQTest[485:17903] 程序开始

2012-06-26 11:06:39.320 WQTest[485:17903] 程序再次激活

2.摁HOME键退出:

2012-06-26 11:08:08.687 WQTest[485:17903] 程序暂停

2012-06-26 11:08:08.690 WQTest[485:17903] 程序进入后台


3.再次进入程序:

2012-06-26 11:09:11.047 WQTest[485:17903] 程序进入前台

2012-06-26 11:09:11.049 WQTest[485:17903] 程序再次激活


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值