首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >viewDidLoad和awakeFromNib计时

viewDidLoad和awakeFromNib计时
EN

Stack Overflow用户
提问于 2011-06-10 14:14:37
回答 4查看 17.8K关注 0票数 10

我的理解是awakeFromNib总是在viewDidLoad之前被调用。

所以我有一个UITableViewController的子类,它是从xib文件中解压出来的。

我在里面定义了这两个方法:

代码语言:javascript
复制
- (void)awakeFromNib {
  [super awakeFromNib];
  NSLog(@"awake from nib");
}

- (void)viewDidLoad {
  [super viewDidLoad];
  NSLog(@"view did load");
}

在控制台中,"view did load“显示在”happens nib“之前。我试图在超级awakeFromNib中使用断点,并反复点击F7 (步入),令我惊讶的是,它在转到awakeFromNib内部的第二行之前进入了-(空)viewDidLoad。

有谁知道这是怎么回事吗?我在常规UIViewController的子类中做了完全相同的事情,日志语句被颠倒了,正如我最初预期的那样……

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-10 15:56:45

为了理解这一事实,我建议您查看NSBundleloadNibNamed:owner:options:方法。

当您从nib初始化一个视图控制器时,它首先加载包含在那里的视图,然后根据nib设置文件所有者属性。当将文件所有者的view属性设置为已加载的视图之一时,将调用viewDidLoad方法。当设置了所有文件所有者插座和属性(包括view属性)时,将调用awakeFromNib。因此,在awakeFromNib之前调用viewDidLoad是有意义的。

希望这能有所帮助

票数 12
EN

Stack Overflow用户

发布于 2011-06-10 18:54:27

我使用基于导航的应用程序选项创建了一个测试项目,并将以下代码添加到rootViewController.m。

代码语言:javascript
复制
- (void)awakeFromNib {
     NSLog(@"awakeFromNib 1");
     [super awakeFromNib];
     NSLog(@"awakeFromNib 2");
}

- (void)viewDidLoad {
     NSLog(@"viewDidLoad 1");
     [super viewDidLoad];
     NSLog(@"viewDidLoad 2");
}

然后,我从控制台得到了结果:

代码语言:javascript
复制
awakeFromNib 1
awakeFromNib 2
viewDidLoad 1
viewDidLoad 2

加载控制器的视图时,将调用-(void)viewDidLoad。因此,当您第一次使用self.view = ...时,-(void)viewDidLoad将被调用。

如果您编写了类似以下内容的代码,则将首先调用-(void)viewDidLoad

代码语言:javascript
复制
  - (void)awakeFromNib {
       NSLog(@"awakeFromNib 1");

       // The log sequence will be funny, if `viewDidLoad` raised before [super awakeFromNib]
       // If you are curios about it, just give it a try.           
       // self.view.backgroundColor = [UIColor clearColor];

       [super awakeFromNib];

       /// viewDidLoad will be called 
       /// because self.view must be loaded first.
       self.view.backgroundColor = [UIColor clearColor];  

       NSLog(@"awakeFromNib 2");
  }

并得到了如下结果。

代码语言:javascript
复制
awakeFromNib 1
viewDidLoad 1
viewDidLoad 2
awakeFromNib 2

更新

如果加载视图成功,loadViewIfNeeded会触发viewDidLoad。有时我会调用loadViewIfNeeded来确保@IBOutlet实例已经初始化,并且不再为空。

票数 6
EN

Stack Overflow用户

发布于 2011-06-10 15:54:41

我不认为你必须在你的超类上调用awakeFromNib。

检查this

编辑

我刚刚运行了一个快速测试,结果如下:

场景1:MainWindow.Xib有一个UIViewController子类TestingAwakeFromNibViewController,它有自己的Nib文件TestingAwakeFromNibViewController.xib

TestingAwakeFromNibViewController有一个名为btn3的UIButton插座。测试以下代码:

代码语言:javascript
复制
- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"Btn3 %@",btn3);

    NSLog(@"viewDidLoad");
}


-(void) awakeFromNib
{
    [super awakeFromNib];

    NSLog(@"Btn3 %@",btn3);

    NSLog(@"awakeFromNib");
}

将打印:

代码语言:javascript
复制
Btn3 (null)
AwakeFromNib
Btn3 <UIRoundedRectButton: 0x64088e0; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x6408890>>
ViewDidLoad

场景2:删除xib文件,将UIView作为son添加到TestingAwakeFromNibViewController inside MainWindow.Xib,将UIButton作为子视图添加到UIView (并将UIbutton插座连接到TestingAwakeFromNibViewController的相应插座)。

现在运行上面的代码将打印:

代码语言:javascript
复制
Btn3 <UIRoundedRectButton: 0x4e31c30; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e31be0>>
viewDidLoad
Btn3 <UIRoundedRectButton: 0x4e31c30; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e31be0>>
awakeFromNib

意思是在AwakeFromNib之前使用ViewDidLoad。

第三个场景:与第二个相同,只是没有调用[super awakeFromNib];

代码语言:javascript
复制
Btn3 <UIRoundedRectButton: 0x4e0ddf0; frame = (114 211; 72 37); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x4e0dda0>>
awakeFromNib

现在,ViewDidLoad甚至都没有被调用。

因此,似乎不同的场景需要不同的行动,我们需要根据我们正在采取的行动做好准备。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6302629

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档