new file...
name:MainViewController
superclass:UIViewController
打开 MainViewController.m
加入
- (id)init
{
self = [super init]; // 调用父类
if (self) {
}
return self;
}
在 self = [super init]; // 调用父类 行设置断点
在 return self; 行设置断点
在 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 行设置断点
在 - (void)viewDidLoad{} 中的 [super viewDidLoad]; 行设置断点
打开 AppDelegate.m
加入#import "MainViewController.h"
在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中加入
// UIViewController生命周期
MainViewController *mainViewController = [[MainViewController alloc] init];
self.window.rootViewController = mainViewController;
在 MainViewController *mainViewController = [[MainViewController alloc] init]; 行设置断点
运行
点击 step into 跳转到 self = [super init];
step over 跳转到 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
//即执行[super init]方法会调用initWithNibName方法
这可以解释
// nib创建2 init查找与视图控制器名字相同的视图显示
/*
RootViewController *rootViewController = [[RootViewController alloc] init];
self.window.rootViewController = rootViewController; // retainCount 2
[rootViewController release];
*/
代码
结论: 如果视图名字与控制器名字相同会被加载
在调试控制台展开第一个self里面的UIViewController 里面对应的就是 UIViewController类中的变量
里面变量 view是空nil
继续 step over 执行完initWithNibName方法 方法执行完会回到 if (self) {}
继续 step over 当执行到- (void)viewDidLoad 方法时视图view变量已经存在 有值了
打开 MainViewController.m
加入
- (void)loadView //以前的xcode会提供该方法
{
}
点击方法名 查看方法说明 (先查看上面定义的view 变量说明)
loadView方法作用说明
//如果不调用该方法会先查找有没有.nib 没有查看有没有.storyboard 如果都没有父类UIViewController会帮助创建一个empty视图然后调用viewDidLoad
//如果有可能会走.nib 或者 .storyboard
如果一定要覆盖该方法loadView 有以下2种方式实现
加入
// 第一种方式:调用父类的loadView //nib storyboard empty
[super loadView];
将[super loadView]; 注释掉加入
// 第二种方式 自定义视图:
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
运行 通过debug观看执行过程
将
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
代码注释掉 即loadView 2种都不写那么loadView方法将会被反复执行
加入 NSLog(@"loadView method");
在 - (void)viewDidLoad 方法最下面加入
// 1.view -> nil 2. getter method 当这2个条件都满足就好循环调用
NSLog(@"%@", self.view);
运行
将 NSLog(@"%@", self.view); 注释掉
将
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
放开
将 initWithNibName 方法中的if{}改为
if (self) {
NSLog(@"%@", self.view);
}
运行
当执行到 eg. NSLog(@"%@", self.view); 时会调用loadView方法
// 创建视图控制器时,不要在初始化方法中,做与视图相关的动作 因为有可能在视图卸载的时候出现一些问题 可以初始化一些数据
将程序运行完
如果存在nib或者storyborad,不要覆盖该方法;手动创建view时,则覆盖该方法
结论: 视图加载过程
首先去访问UIViewController中的view属性 如果存在view,则直接加载。相反,如果不存在,则UIViewController会调用父类的loadView方法
loadView方法执行如下操作:如果你自定义Custom Method即覆盖了该方法loadView,则必须创建view给UIViewController的view属性
如果你没有覆盖该方法,父类方法会判断是否有storyboard或者nib如果有会通过它加载一个view 如果没有会创建一个empty view
UIViewController最后会调用父类的方法viewDidLoad方法返回view
循环调用的问题:最好不要在init方法写跟视图方法相关的代码
一旦覆盖方法loadView就一定要创建一个视图给视图控制器 1.可以调用父类的loadView // 第二种方式 自定义视图
否则视图创建就会失败 引发循环调用
4. 视图控制器视图的出现与消失
理解各个方法执行顺序
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
- (void) loadView
- (void) viewDidLoad // 解释 [super viewDidLoad]
- (void) viewWillAppear:(BOOL)animated
- (void) viewDidAppear:(BOOL)animated
- (void) viewWillDisappear:(BOOL)animated
- (void) viewDidDisappear:(BOOL)animated
//后2个方法在模态视图中演示说明
打开 MainViewController.m
加入
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"viewWillAppear");
} // 视图将要出现执行
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"viewdidAppear");
} // 视图已经出现,此时视图已渲染完毕执行
运行
为什么要在各个方法中都调用父类的方法呢??? [super viewDidAppear:animated] [super viewWillAppear:animated]
- (void)loadView 方法修改为
- (void)loadView
{
// 第一种方式:调用父类的loadView
// [super loadView];
// 第二种方式 自定义视图:
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
// add subView
UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(60, 100, 200, 200)];
subView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:subView];
[subView release];
}
new file ... name:SubViewController
superclass:MainViewController
SubViewController.m 修改为
#import "SubViewController.h"
@interface SubViewController ()
@end
@implementation SubViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView
{
[super loadView]; // 调用父类的方法 MainViewController
// add subviews
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor purpleColor];
}
- (void)viewWillUnload
{
[super viewWillUnload];
NSLog(@"viewWillUnload");
}
- (void)viewDidUnload
{
[super viewDidUnload];
NSLog(@"viewDidUnload");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
NSLog(@"didReceiveMemoryWarning");
// Dispose of any resources that can be recreated.
}
@end
打开 AppDelegate.m 加入
#import "SubViewController.h"
在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 中加入
MainViewController *mainViewController = [[MainViewController alloc] init];
self.window.rootViewController = mainViewController;
[mainViewController release];
运行
将
MainViewController *mainViewController = [[MainViewController alloc] init];
self.window.rootViewController = mainViewController;
[mainViewController release];
注释掉加入
SubViewController *viewController = [[SubViewController alloc] init];
self.window.rootViewController = viewController;
[viewController release];
运行
以上解释了为什么 在
- (void)viewDidLoad{} 中调用要调用父类的 [super viewDidLoad];
- (void)loadView{}中调用父类的 [super loadView];
原因
视图加载执行顺序
- (void)loadView{}
- (void)viewDidLoad{}
- (void) viewWillAppear:(BOOL)animated
- (void) viewDidAppear:(BOOL)animated
name:MainViewController
superclass:UIViewController
打开 MainViewController.m
加入
- (id)init
{
self = [super init]; // 调用父类
if (self) {
}
return self;
}
在 self = [super init]; // 调用父类 行设置断点
在 return self; 行设置断点
在 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 行设置断点
在 - (void)viewDidLoad{} 中的 [super viewDidLoad]; 行设置断点
打开 AppDelegate.m
加入#import "MainViewController.h"
在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 方法中加入
// UIViewController生命周期
MainViewController *mainViewController = [[MainViewController alloc] init];
self.window.rootViewController = mainViewController;
在 MainViewController *mainViewController = [[MainViewController alloc] init]; 行设置断点
运行
点击 step into 跳转到 self = [super init];
step over 跳转到 self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
//即执行[super init]方法会调用initWithNibName方法
这可以解释
// nib创建2 init查找与视图控制器名字相同的视图显示
/*
RootViewController *rootViewController = [[RootViewController alloc] init];
self.window.rootViewController = rootViewController; // retainCount 2
[rootViewController release];
*/
代码
结论: 如果视图名字与控制器名字相同会被加载
在调试控制台展开第一个self里面的UIViewController 里面对应的就是 UIViewController类中的变量
里面变量 view是空nil
继续 step over 执行完initWithNibName方法 方法执行完会回到 if (self) {}
继续 step over 当执行到- (void)viewDidLoad 方法时视图view变量已经存在 有值了
打开 MainViewController.m
加入
- (void)loadView //以前的xcode会提供该方法
{
}
点击方法名 查看方法说明 (先查看上面定义的view 变量说明)
loadView方法作用说明
//如果不调用该方法会先查找有没有.nib 没有查看有没有.storyboard 如果都没有父类UIViewController会帮助创建一个empty视图然后调用viewDidLoad
//如果有可能会走.nib 或者 .storyboard
如果一定要覆盖该方法loadView 有以下2种方式实现
加入
// 第一种方式:调用父类的loadView //nib storyboard empty
[super loadView];
将[super loadView]; 注释掉加入
// 第二种方式 自定义视图:
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
运行 通过debug观看执行过程
将
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
代码注释掉 即loadView 2种都不写那么loadView方法将会被反复执行
加入 NSLog(@"loadView method");
在 - (void)viewDidLoad 方法最下面加入
// 1.view -> nil 2. getter method 当这2个条件都满足就好循环调用
NSLog(@"%@", self.view);
运行
将 NSLog(@"%@", self.view); 注释掉
将
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
放开
将 initWithNibName 方法中的if{}改为
if (self) {
NSLog(@"%@", self.view);
}
运行
当执行到 eg. NSLog(@"%@", self.view); 时会调用loadView方法
// 创建视图控制器时,不要在初始化方法中,做与视图相关的动作 因为有可能在视图卸载的时候出现一些问题 可以初始化一些数据
将程序运行完
如果存在nib或者storyborad,不要覆盖该方法;手动创建view时,则覆盖该方法
结论: 视图加载过程
首先去访问UIViewController中的view属性 如果存在view,则直接加载。相反,如果不存在,则UIViewController会调用父类的loadView方法
loadView方法执行如下操作:如果你自定义Custom Method即覆盖了该方法loadView,则必须创建view给UIViewController的view属性
如果你没有覆盖该方法,父类方法会判断是否有storyboard或者nib如果有会通过它加载一个view 如果没有会创建一个empty view
UIViewController最后会调用父类的方法viewDidLoad方法返回view
循环调用的问题:最好不要在init方法写跟视图方法相关的代码
一旦覆盖方法loadView就一定要创建一个视图给视图控制器 1.可以调用父类的loadView // 第二种方式 自定义视图
否则视图创建就会失败 引发循环调用
4. 视图控制器视图的出现与消失
理解各个方法执行顺序
- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
- (void) loadView
- (void) viewDidLoad // 解释 [super viewDidLoad]
- (void) viewWillAppear:(BOOL)animated
- (void) viewDidAppear:(BOOL)animated
- (void) viewWillDisappear:(BOOL)animated
- (void) viewDidDisappear:(BOOL)animated
//后2个方法在模态视图中演示说明
打开 MainViewController.m
加入
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
NSLog(@"viewWillAppear");
} // 视图将要出现执行
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
NSLog(@"viewdidAppear");
} // 视图已经出现,此时视图已渲染完毕执行
运行
为什么要在各个方法中都调用父类的方法呢??? [super viewDidAppear:animated] [super viewWillAppear:animated]
- (void)loadView 方法修改为
- (void)loadView
{
// 第一种方式:调用父类的loadView
// [super loadView];
// 第二种方式 自定义视图:
UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
view.backgroundColor = [UIColor orangeColor];
self.view = view; // 赋值
[view release];
// add subView
UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(60, 100, 200, 200)];
subView.backgroundColor = [UIColor yellowColor];
[self.view addSubview:subView];
[subView release];
}
new file ... name:SubViewController
superclass:MainViewController
SubViewController.m 修改为
#import "SubViewController.h"
@interface SubViewController ()
@end
@implementation SubViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)loadView
{
[super loadView]; // 调用父类的方法 MainViewController
// add subviews
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor purpleColor];
}
- (void)viewWillUnload
{
[super viewWillUnload];
NSLog(@"viewWillUnload");
}
- (void)viewDidUnload
{
[super viewDidUnload];
NSLog(@"viewDidUnload");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
NSLog(@"didReceiveMemoryWarning");
// Dispose of any resources that can be recreated.
}
@end
打开 AppDelegate.m 加入
#import "SubViewController.h"
在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 中加入
MainViewController *mainViewController = [[MainViewController alloc] init];
self.window.rootViewController = mainViewController;
[mainViewController release];
运行
将
MainViewController *mainViewController = [[MainViewController alloc] init];
self.window.rootViewController = mainViewController;
[mainViewController release];
注释掉加入
SubViewController *viewController = [[SubViewController alloc] init];
self.window.rootViewController = viewController;
[viewController release];
运行
以上解释了为什么 在
- (void)viewDidLoad{} 中调用要调用父类的 [super viewDidLoad];
- (void)loadView{}中调用父类的 [super loadView];
原因
视图加载执行顺序
- (void)loadView{}
- (void)viewDidLoad{}
- (void) viewWillAppear:(BOOL)animated
- (void) viewDidAppear:(BOOL)animated