1
1
1,N
1,N
尽管有些书上说可以绕过UIViewController直接对UIView进行操作,但个人认为此层的作用用于管理视图和视图关系
下面分别对上述层次关系的对象类型进行学习。说明下,下面学习的东西仅和问题有关,不会全面学习类中的各种方法和属性。
UIApplication
继承于UIResponder:NSObject
框架:UIKit.framework
头文件:UIApplication.h
每一个应用程序都有一个UIApplication或其子类型的实例。当程序被加载,函数方法UIApplicationMain就被调用执行,它创建了单件模式的UIApplication对象。之后你可以通过执行sharedApplication类方法来访问。
看看main函数
@class NavSmallPhoneViewControl
@interface NavSmallPhoneAppDelegate
}
@property (nonatomic, retain) IBOutlet UIWindow * window;
@property (nonatomic, retain) IBOutlet NavSmallPhoneViewControl
@end
#import " NavSmallPhoneViewControl
@implementation NavSmallPhoneAppDelegate
@synthesize window = _window;
@synthesize viewController = _viewController;
@synthesize info;
- (BOOL)application:(UIApplication * )application didFinishLaunchingWithOp
{
// 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程序对象结构如下:
对象个数
1
1
1
1
1,N
1,N
根据现在的对象结构图,可以知道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为复杂视图控制器和视图的层次结构提供额外的行为处理功能。
针对问题看下,有哪些视图控制器可访问?
最关键,怎么去管理视图?
属性view和方法loadView
UIView又如何得到它的操作者?又如何管理自身的子视图?
继承于UIResponder:NSObject
如果UIView包含在UIViewController下,只能顺起获取到对应的UIView,暂时未知如何根据UIView获取UIViewController
UIView关于管理视图层次,如下:
Managing the View Hierarchy
感觉可以通过属性window来获取Controller,从某一个角度来说,这个Controller应该是当前视图的父对象
=======================================================================================================
UIView.window属性来源于当前UIApplication.keyWindow
可以通过此属性让UIView间接获取到该视图的UIViewController类
文中涉及红色粗体,是本文的相关答案标记。

- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- // Override point for customization after application launch.
- NSLog(@"程序开始");
- return YES;
- }
- - (void)applicationWillResignActive:(UIApplication *)application
- {
- // 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.
- // 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.
- NSLog(@"程序暂停");
- }
- - (void)applicationDidEnterBackground:(UIApplication *)application
- {
- // 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.
- // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
- NSLog(@"程序进入后台");
- }
- - (void)applicationWillEnterForeground:(UIApplication *)application
- {
- // 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.
- NSLog(@"程序进入前台");
- }
- - (void)applicationDidBecomeActive:(UIApplication *)application
- {
- // 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.
- NSLog(@"程序再次激活");
- }
- - (void)applicationWillTerminate:(UIApplication *)application
- {
- // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
- NSLog(@"程序意外终止");
- }
实验结果:
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] 程序再次激活