-viewDidLoad未在子类UIViewController中调用 [英] -viewDidLoad not called in subclassed 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 $ c $
b
MyViewController * myViewController = [[MyViewController alloc] init];
[superView addSubview:myViewController.view]; //调用viewDidLoad。
那么 loadView
和<$ c $
但是,如果您的代码如下所示:
$ b $ b
MyViewController * myViewController = [[MyViewController alloc] init];
查看 getter可以看到你' ve已经加载了视图,并且它假设你也调用了
[myViewController loadView];
[superView addSubview:myViewController.view]; //不调用viewDidLoad。
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
, aUIViewController
subclass. FooViewController.xib has its File's Owner set to FooViewController. Additionally, I haveMain
, whose App Delegate isMyApplication
and whose File's Owner isUIApplication
. 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 afterloadView
is called, and it's up to whomever callsloadView
to supply the extra call toviewDidLoad
.In some cases, the SDK will handle this behavior for you. Suppose you have a subclass of
UIViewController
calledMyViewController
; then:
- If you access
myViewController.view
before you callloadView
, then the superclass accessor is smart enough to callloadView
for you, andviewDidLoad
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屋!