控制器以及view的多种创建方式、 控制器的生命周期方法

控制器以及view的多种创建方式
控制器的生命周期方法
如何创建一个控制器

系统自动实现过程
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // 1.创建window
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    
    // 2.加载storyboard,并且创建初始化控制器(箭头所指的控制器)
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    self.window.rootViewController = [storyboard instantiateInitialViewController];
    
    // 3.显示窗口
    [self.window makeKeyAndVisible];
    
    return YES;
}


1、直接创建
 MJOneViewController *one = [[MJOneViewController alloc] init];
 one.view.backgroundColor = [UIColor blueColor];
  self.window.rootViewController = one;

  
2、控制器常见的创建方式有以下几种
通过storyboard创建
   UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Two" bundle:nil];
// UIViewController *vc = [storyboard instantiateInitialViewController];
    MJTwoViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"pink"];
    self.window.rootViewController = vc;
    
    
3、指定xib文件来创建
 self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
 self.window.backgroundColor = [UIColor whiteColor];
    
 MJThreeViewController *three = [[MJThreeViewController alloc] initWithNibName:@"MJThree5345" bundle:nil];

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



ViewController的view的创建

  /**
  控制器创建好以后, 控制器所管理的View是如何创建的?
 1> 控制器的View是通过调用控制器的loadView方法来创建的。这个方法是UIViewController中的一个方法。
    ** 只要控制器的loadView方法被调用了, 那么证明控制器的View创建好了。
 2> 当调用完毕控制器的loadView方法以后, 从这时开始, 才创建好了控制器的view
 3> 当控制器的View被创建好以后, 紧接着就调用控制器的viewDidLoad方法
 4> 控制器的View采用了懒加载的方式, 也就是说, 在需要的使用(在用到的时候)才会创建(调用loadView方法)。
 
 ** 注意: 无论控制器是如何创建的, 只要在控制器中, 重写了("实现了")loadView方法, 并且没有调用[super loadView]方法, 那么最终控制器的View就必须完全在loadView方法中自己来创建了。所以loadView方法可以用来自定义View。
   */
   
   
 ** 控制器中的View的几种创建方式:
  1. 先介绍self.view是通过loadView来加载的。
     // 当第一次从self.view中获取view的时候(第一次使用self.view的时候),
     // 控制器会调用它自己的loadView方法先创建一个view, 并且把这个新创建的view设置给self.view, 然后我们就能够通过self.view获取控制器的view了
     // 控制器的view, 是通过哪个方法创建出来的。
     // 控制器的view也是通过"懒汉式"来加载的。(控制器的view也是采用懒加载模式)

  
- (void)loadView
{
    if (如果是直接通过alloc + init方法直接创建的控制器) {
        self.view =  [[UIView alloc] init];
   } else if (如果是通过storyboard创建的控制器) {
       // 加载storyboard中的控制器, 并把storyboard中的控制器设置给self.view
   } else if (通过xib创建的控制器) {
       // 加载xib中的view, 并把xib中的view设置给self.view
   }
}

 - (void)loadView
 {
     [super loadView];
 //如果希望完全自定义一个控制器的view, 那么就重写loadView方法, 同时一定不要调用父类的loadView方法。只要调用了父类的loadView方法, 那么就会执行默认的创建控制器的view的行为。
 self.view = [[UIView alloc] init];
 }
 
 
 1. 通过storyboard创建, 创建完控制器后, 自动调用loadView方法,创建控制器的view。
    ** 此时自定义的控制器, 因为没有"重写"("实现")loadView方法, 所以loadView方法内部就是根据storyboard文件中的view来创建View的。
2. 通过xib文件创建, 创建完控制器后, 自动调用loadView创建控制器的view。
     ** 此时自定义的控制器, 因为没有"重写"("实现")loadView方法, 所以loadView方法内部就是根据storyboard文件中的view来创建View的。
     ** 通过xib文件创建控制器的时候, 注意xib文件的名字
	1> 如果创建控制器的时候, 通过initWithNibName指定了xib的名字, 那么就根据该xib创建view
	2> 如果创建控制器的时候, 没有指定任何xib文件, 也没有相应的storyboard文件, 那么会尝试查找"与控制器名字相同的, 但是去除Controller的文件名的xib文件"。比如: 控制器叫做"CZViewController", 就会查找"CZView.xib"文件, 如果有, 则使用该xib文件创建view(无需手动指定, 系统自动查找)。
	3> 如果创建控制器的时候, 没有指定任何xib文件, 也没有相应的storyboard文件, 也没有"CZView.xib", 那么会尝试查找与控制器名字完全相同的xib文件。比如: 控制器叫做"CZViewController", 就会查找"CZViewController.xib"文件, 如果有, 则使用该xib文件创建view(无需手动指定, 系统自动查找)。
      ** 建议: 如果要使用某个xib文件名自动匹配的方式创建view, 建议名字与控制器相同。

3. 通过重写(实现)UIViewController的loadView方法重写。(自己通过代码来创建控制器的View)
     *** 控制器的loadView方法就是用来自定义View的。
     ** 如果要为控制器自定义View, 要写在loadView中, 不要写在viewDidLoad中。
     *** 如果重写(实现)loadView方法中调用了[super loadView], 那么依然会使用默认的方式来加载。
     *** 重写ViewController的loadView方法,用来自定义View。
     
参考代码:
  // 重写控制器的loadView方法:
   - (void)loadView
  {
    // [super loadView];
     self.view = [[UIView alloc] init];
    self.view.backgroundColor = [UIColor purpleColor];
  }

通过xib创建view的时候, 如果重写loadView返回的是一个透明的view,不是xib中的view
 - (void)loadView
 {
 [super loadView];
 NSLog(@"loadView");
 //self.view.backgroundColor = [UIColor blueColor];
 }

** 注意:无论是通过加载xib创建view、storyboard创建view, 最终都依赖于loadView方法。
** 注意:修改了项目文件(比如:xxx.xib等,要先Product -> Clean, 然后把软件从模拟器中卸载, 然后再运行。)
** 如果除非手动指定了xib文件名,则按照该文件来加载,否则如果没有指定任何文件名字,则按照对应的xib文件的命名规则来找对应的xib文件。

** 控制器的loadView方法什么时候调用?
** 在需要用到控制器的view的时候才调用(当调用UIWindow对象的makeKeyAndVisible方法时,就需要显示该view了, 此时就表示用到View了。), 这个就叫做"延迟加载"。
** 比如当使用self.view.backgroundColor , 要设置控制器的view的背景色时(这时需要用到view了), 那么此时才会开始创建该控制器的view, 也就是说要调用loadView方法了。所以, 如果在loadView方法内部调用self.view.backgroundColor, 就发生死循环了。
** 可以通过调用控制器的self.isViewLoaded 方法来判断当前控制器的view是否已经加载完毕了。
** 并且当控制器的view加载完毕后, 会调用viewDidLoad方法。
** 演示控制器中的View的延迟加载效果(用到的时候才加载。)演示在loadView方法内部使用view,比如self.view.backgroundColor来设置背景色, 此时会发生死循环。
** 在loadView方法, viewDidLoad方法中输出内容。调试看在调用UIWindow的makeKeyAndVisible方法之前,是否会调用这些方法。
** 当需要访问view的时候, 调用loadView, 然后调用viewDidLoad方法, 然后才开始使用view。

控制器view的延迟加载
控制器的view是延迟加载的:用到时再加载
可以用isViewLoaded方法判断一个UIViewController的view是否已经被加载
控制器的view加载完毕就会调用viewDidLoad方法


你可能感兴趣的:(view,控制器,创建方式,控制器生命周期)