UIViewController初始化和加载顺序

我对Mac和iPhone上的UI编程相当陌生,并且遇到了让我感到困惑的东西。

一个UIViewController有3个方法涉及它的初始化和它的视图:

  • init(和类似init的方法)
  • 的loadView
  • viewDidLoad(委托方法)
  • 我希望这些发生在上面的顺序。 第一个UIViewController由其他对象分配,然后立即调用init(或者其他init方法,如initWithStyle)。

    只有对象被初始化后,我才会期望它调用它自己的loadView函数,之后视图一旦加载,就会调用viewDidLoad委托方法。

    这不会发生,例如:

    @implementation UIViewControllerSubclass
    
    - (id)init {
            NSLog(@"0");
        if (self = [super init]) {
            NSLog(@"1");
        }
        return self;
    }
    
    - (void)loadView {
        [super loadView];
        NSLog(@"2");
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSLog(@"3");
    }
    
    @end
    

    生成控制台输出:

    0
    2
    3
    1
    

    因此,loadView和viewDidLoad方法不能进行委托调用,因为通常在调用[super init]之后设置委托,在loadView和viewDidLoad运行后调用该委托(如上所示):

    UIViewControllerSubClass *someViewController = [[UIViewControllerSubclass alloc] init];
    [viewController setDelegate:self];
    

    如果我想要以某种方式运行设置ViewController的代码,请将代码通知给它,代码应该驻留在init方法中吗? loadView存在的原因是不是允许这样的代码在适当的时候运行?

    在我看来,我将不得不创建一个新的initWithDelegate方法,它在调用[super init]之前设置代理ivar,这是对的,还是我以错误的方式去做这件事?

    提前致谢 :)


    iPhone上的视图加载系统的工作原理如下:

    当初始化视图控制器(使用-init或-initWithNibName:bundle :)时,它实际上并不创建和初始化视图。 当你第一次调用-view时,它会调用-loadView。 默认情况下,-loadView只是从xib文件(nibName)加载视图。 但是,如果您重写此视图,则需要负责创建视图并将其分配给视图控制器的视图属性。 举个例子:

    - (void)loadView
    {
       UIView *view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
       // add subviews 
       self.view = view;
       [view release];
    }
    

    每次创建视图时,视图都会变得可见并显示在屏幕上,它会调用-viewDidLoad。 (-viewDidAppear / -viewDidDisappear是为了在屏幕上显示视图的可见性)

    由于我们已经脱轨,我们考虑内存管理。 当视图离屏时,系统会自动将视图控制器的视图属性设置为零。 问题是该视图的所有子视图都在泄漏。 怎么会这样? 那么,每个子视图的保留计数是2(视图保留子视图,并且您的视图控制器有一个出口/ ivar)。 当视图为nil时,该视图的保留计数为1.如果未显示视图,视图仍然存在并没有意义,所以将其设置为nil,即-viewDidUnload(这是每当视图设置为零)。


    initWithNibName:bundle:方法是UIViewController类的指定初始值设定项。

    尝试覆盖并使用它而不是init:

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
        if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        }
        return self;
    }
    

    ...

    UIViewControllerSubClass *someViewController = [[UIViewControllerSubclass alloc] initWithNibName:@"UIViewControllerSubclass" bundle:nil];
    

    -(void)awakeFromNib
    {
    }
    

    仅在您使用故事板来存储在故事板Nib中绘制的ViewController时才被调用 - 意味着界面包。

    正确的顺序是

    -(void)initWithCoder
    -(void)awakefromNib    //(if story board is used)
        or
    -(void)loadView----() //if manually generating the view contoller
    
    -(void)viewDidLoad-----(called only once in the life cycle of viewController)
    -(void)viewWillAppear
    -(void)viewDidAppear
    

    在移动到一个新的ViewController时

    -(void)viewWillDisappear
    -(void)viewDidDisappear
    

    而返回到第一个ViewController

    -(void)viewWillAppear
    -(void)viewDidAppear
    
    链接地址: http://www.djcxy.com/p/87711.html

    上一篇: Order of UIViewController initialization and loading

    下一篇: How to use a 'Container View' in iOS?