-viewDidLoad未在子类UIViewController中调用 [英] -viewDidLoad not called in subclassed UIViewController

查看:92
本文介绍了-viewDidLoad未在子类UIViewController中调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有耐心与我,我还在学习Cocoa Touch。其他--viewDidLoad未被调用的问题与我的问题无关,我搜索过。



我有 FooViewController UIViewController 子类。 FooViewController.xib将其文件的所有者设置为FooViewController。此外,我有 Main ,其应用程序代理 MyApplication ,其文件所有者 UIApplication 。我的主要笔尖设置为Main。



我可以使视图出现在屏幕上,使用此流程(代码简洁):

  UIWindow * main; 

- (void)applicationDidFinishLaunching:(UIApplication *)application {
[self showFooViewController];
[main makeKeyAndVisible];
}

- (void)showFooViewController {
fooViewController = [[FooViewController alloc] init];
if(![[NSBundle mainBundle] loadNibNamed:@FooViewControllerowner:fooViewController options:nil]){
DebugF(@Failed to load FooViewController);
return;
}

//添加视图并将其放置到位
UIView * view = [fooViewController view];
CGRect cur = [view frame];
cur.origin = CGPointMake(0.0f,20.0f);
[view setFrame:cur];

[main addSubview:[fooViewController view]];
}

但是,此消息未发送到 FooViewController

   - (void)viewDidLoad {
DebugF(@Hello! ;
}

gdb输出中的总静默。



我看过其他Cocoa教程,在IB的文档视图中显示Instances等,但是我在我的项目中没有看到这些选项。我应该在Nib中实例化fooViewController吗?我错过了连接吗?在FooViewController.xib中,文件的所有者视图连接到Nib中的视图。



我相信这是一个简单的解决方案,我已经走错了路径。 Halp!

解决方案

我没有找到文档来备份以下内容,但这是我通过实验/经验推断的:



viewDidLoad 方法预计会在 loadView 被调用,并且由谁调用 loadView 以向 viewDidLoad 提供额外的调用。



在某些情况下,SDK会为您处理此行为。假设你有一个子类 UIViewController 调用 MyViewController ;那么:




  • 如果在调用<$ c $之前访问 myViewController.view c> loadView ,那么超类访问器可以聪明地为你调用 loadView ,并且 viewDidLoad
    b

      MyViewController * myViewController = [[MyViewController alloc] init]; 
    [superView addSubview:myViewController.view]; //调用viewDidLoad。

    那么 loadView 和<$ c $



    但是,如果您的代码如下所示:


    $

    b $ b

      MyViewController * myViewController = [[MyViewController alloc] init]; 
    [myViewController loadView];
    [superView addSubview:myViewController.view]; //不调用viewDidLoad。
    查看 getter可以看到你' ve已经加载了视图,并且它假设你也调用了 viewDidLoad ,所以它也不会调用。讽刺的是,这里的额外函数调用阻止 viewDidLoad 被调用。


    Have patience with me, I'm still learning Cocoa Touch. Other -viewDidLoad not being called question was unrelated to my issue, I did search.

    I have FooViewController, a UIViewController subclass. FooViewController.xib has its File's Owner set to FooViewController. Additionally, I have Main, whose App Delegate is MyApplication and whose File's Owner is UIApplication. My primary nib is set to Main.

    I am able to make the view appear on the screen, using this flow (code snipped for brevity):

    UIWindow *main;
    
    -(void)applicationDidFinishLaunching:(UIApplication*)application {
        [self showFooViewController];
        [main makeKeyAndVisible];
    }
    
    -(void)showFooViewController {
        fooViewController = [[FooViewController alloc] init];
        if(![[NSBundle mainBundle] loadNibNamed:@"FooViewController" owner:fooViewController options:nil]) {
            DebugF(@"Failed to load FooViewController");
            return;
        }
    
        // Add the view and put it in place
        UIView *view = [fooViewController view];
        CGRect cur = [view frame];
        cur.origin = CGPointMake(0.0f, 20.0f);
        [view setFrame:cur];
    
        [main addSubview:[fooViewController view]];
    }
    

    However, this message is not being sent to FooViewController:

    - (void) viewDidLoad {
        DebugF(@"Hello!");
    }
    

    Total silence in gdb's output.

    I've seen other Cocoa tutorials that show Instances and such in IB's document view, but I do not see these options in mine. Am I supposed to be instantiating fooViewController in the Nib? Did I miss a connection? In FooViewController.xib, File's Owner view is connected to the view in the Nib.

    I'm sure this is a simple solution, and I have wandered down the wrong path. Halp!

    解决方案

    I have not found documentation to back up the following, but this is what I've deduced by experiment / experience:

    The viewDidLoad method is expected be called immediately after loadView is called, and it's up to whomever calls loadView to supply the extra call to viewDidLoad.

    In some cases, the SDK will handle this behavior for you. Suppose you have a subclass of UIViewController called MyViewController; then:

    • If you access myViewController.view before you call loadView, then the superclass accessor is smart enough to call loadView for you, and viewDidLoad immediately thereafter.

    As a result, if your code looks like this:

    MyViewController *myViewController = [[MyViewController alloc] init];
    [superView addSubview:myViewController.view];  // Calls viewDidLoad.
    

    then both loadView and viewDidLoad will be called on your behalf.

    However, if your code looks like this:

    MyViewController *myViewController = [[MyViewController alloc] init];
    [myViewController loadView];
    [superView addSubview:myViewController.view];  // Doesn't call viewDidLoad.
    

    then the view getter can see you've already loaded the view, and it assumes you also called viewDidLoad as well - so it doesn't call either. Ironically, the extra function call here prevents viewDidLoad from getting called.

    这篇关于-viewDidLoad未在子类UIViewController中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆