黑马程序员——IOS应用程序初步认识
------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
1. 应用界面的结构
(1) 每一个应用的界面一般有状态栏和该应用程序自己的UIWindow( UIWindow 继承与 UIView )
(2) UIWindow上面有可以放置很多UIView
(3) 跟用户进行交互的是UIWindow
2. 程序的主体构架
从上面图片我们很容易想到以下问题 :
(1) 谁来管理UIView的生命周期?
(2) 谁来管理UIView之间的切换?
(3) 谁来给UIView装配数据?
(4) 谁来监听UIView的事件?
以上答案都是UIViewController,每一个UIViewController.那么 UIViewController Model(数据源) UIView 三者之间的关系如下 :
这就是经典的 MVC 构架 : UIViewController相当于一个中介者,用来负责管理UIView 和 Model的通信.这种设计模式很好地把各类代码分离,降低了代码维护的难度。
3. 应用程序运行的原理
从一个简单地singleViewApplication来看,程序的入口为main函数:
(1) 执行 int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName); 函数 :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// main.m #import <UIKit/UIKit.h> #import "MJAppDelegate.h" int main( int argc, char *argv[]) { @autoreleasepool { /* * 参数 1 和 参数 2接受了main函数的两个参数 * 参数 3 : 接受一个 继承与 UIApplication 的类的名称字符串,如果为空,则默认使用 NSStringFromClass( [UIApplication class] ) * 参数 4 : 接收一个应用程序的代理类的名称的字符串 */ return UIApplicationMain(argc, argv, nil, NSStringFromClass([MyAppDelegate class ])); } } |
(2) 通过这个函数首先会创建一个 UIApplication 的单例对象,然后开启一个main loop 消息循环
(3) 然后根据传入的类名创建和设置UIApplication代理,通过给代理对象发送消息来监听 UIApplication 的生命周期
(4) 在UIApplication加载完毕后发送消息给代理完成UIWindow的初始化工作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
// MyAppDelegate.m #import "MyAppDelegate.h" #import "MyViewController.h" @implementation MyAppDelegate - ( void )dealloc { [_window release]; [_viewController release]; [super dealloc]; } - ( BOOL )application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions // 在应用程序加载完毕之后调用 { NSLog(@ "didFinishLaunchingWithOptions-加载完毕" ); // 初始化一个窗口 self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; // 传入xib文件名来初始化一个控制器 self.viewController = [[[MJViewController alloc] initWithNibName:@ "MJViewController" bundle:nil] autorelease]; // 设置窗口的根控制器 self.window.rootViewController = self.viewController; // 上面的代码内部执行了下面代码的操作 // [self.window addSubview:self.viewController.view]; // 窗口不会默认显示,需要调用方法来显示 // keyWindow是主窗口,只有主窗口才能跟用户正常交互 [self.window makeKeyAndVisible]; // self.window.hidden = NO; return YES; } - ( void )applicationWillResignActive:(UIApplication *)application // 程序失去焦点的时候调用(不能跟用户进行交互了) { NSLog(@ "applicationWillResignActive-失去焦点" ); } - ( void )applicationDidEnterBackground:(UIApplication *)application // 当应用程序进入后台的时候调用(点击HOME键) { NSLog(@ "applicationDidEnterBackground-进入后台" ); } - ( void )applicationWillEnterForeground:(UIApplication *)application // 当应用程序进入前台的时候调用 { NSLog(@ "applicationWillEnterForeground-进入前台" ); } // 获取焦点之后才可以跟用户进行交互 - ( void )applicationDidBecomeActive:(UIApplication *)application // 当应用程序获取焦点的时候调用 { NSLog(@ "applicationDidBecomeActive-获取焦点" ); } - ( void )applicationWillTerminate:(UIApplication *)application // 程序在某些情况下被终结时会调用这个方法 { NSLog(@ "applicationWillTerminate-被关闭" ); } @end |
4. UIView事件的绑定
由于UIView的事件处理是由 UIViewController 来负责处理的,因此成员变量的设定在UIViewController上:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// MJViewController.h #import <UIKit/UIKit.h> @interface MJViewController : UIViewController // UI元素一般用assign即可 /* 这些UI元素声明周期已经被UIView很好地管理了, 而UIView已经作为UIViewController的成员变量它的生命周期已经得到很好地管理了 因此管理了UIView的声明周期相当于管理了UIView的子元素的生命周期 因此这里无须额外增加管理生命周期的工作量,使用assign即可 */ // IBOutlet 可以让子元素成员变量显示到xib文件中 @property (nonatomic, assign) IBOutlet UITextField *qq; @property (nonatomic, assign) IBOutlet UITextField *pwd; // IBAction其实就是void // IBAction可以让方法名,显示到xib文件右击列表中 - (IBAction)login; @end |
a. UIViewController的UIView的赋值
b. 获得UIView子元素的引用
c. UIView点击事件绑定
5. 点击事件处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
#import "MJViewController.h" @interface MJViewController () @end @implementation MJViewController #pragma mark 登录 - ( void )login { // 获取文本输入框的内容 NSString *qqText = _qq.text; NSString *pwdText = _pwd.text; NSLog(@ "QQ=%@,密码=%@" , qqText, pwdText); // 暂时理解:叫出键盘的那个视图就是第一个响应者(FirstResponder) // resignFirstResponder代表这个视图不想当第一响应者了,于是键盘就会退出 //[_qq resignFirstResponder]; //[_pwd resignFirstResponder]; // 如果第一响应者存在于self.view里面,就可以退出键盘 [self.view endEditing:YES]; } - ( void )viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - ( void )didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end |
6. 总结
(1) 应用程序基本构架是 M(数据源),V(视图,UIView),C(UIViewController),UIViewController包含UIView,和数据源,当UIView需要数据来更新界面时候通过UIViewController来收集用户的数据,然后UIViewController把处理好的数据发送给UIView并控制其更新。
(2) 应用程序启动过程大概经历以下步骤 :
1) 执行 UIApplicationMain 函数,传入UIApplication的类名,和UIApplication代理的类名
2) 开启 main loop 消息循环,创建 UIApplication 对象,并创建代理来监听 UIApplication 的生命周期
3) 当 UIApplication 加载完毕时候会发送 - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 消息给代理
4) 这时在此方法中完成界面初始化工作 :
a. 初始化UIWindow对象
b. 根据xib文件创建UIViewController
c. 把窗口的控制器成为UIWindow的根控制器(里面至少执行了把 UIViewController 的UIView添加到 UIWindow上 : [self.window addSubview:self.viewController.view];)
d. 让该 UIWindow 对象成为keyWindow来完成与用户之间的交互。
(4) 对于事件处理 首先给相应地方法绑定IBAction标志,然后在xib文件中进行绑定
(5) 要处理UIView元素的数据首先获得其引用(assign策略),然后使用IBOutlet来在xib绑定引用.
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。