UIViewController生命周期

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值