我应该使用哪个,-awakeFromNib 还是 -viewDidLoad?

Posted

技术标签:

【中文标题】我应该使用哪个,-awakeFromNib 还是 -viewDidLoad?【英文标题】:Which should I use, -awakeFromNib or -viewDidLoad? 【发布时间】:2008-12-18 08:28:31 【问题描述】:

我最近在我的应用程序中遇到了一个问题,我在 UIViewController 子类的 -awakeFromNib 方法中创建的一些子视图从视图中消失了。经过一番摸索,我发现将我放入 -awakeFromNib 的代码移动到 -viewDidLoad 解决了这个问题。似乎-awakeFromNib 在从笔尖取消归档 UIViewController 时只调用一次,而每次取消归档视图时都会调用 -viewDidLoad

那么最佳做法是什么?看起来 UIViewController 的 -awakeFromNib 不应该在视图中添加任何视图,这种事情应该在 -viewDidLoad 中完成。我是否正确理解这一点?还是我比我想象的更困惑?

【问题讨论】:

请记住,viewDidLoad 仅适用于视图控制器,不适用于视图本身。 awakeFromNib 实际上适用于“一切”,因为它是 NSObject 的一部分。请记住,如果处理视图不运行,例如,在 awakeFromNib 中的动画,因为视图仍然很可能被动画到位置等。 【参考方案1】:

awakeFromNibcontroller 本身从 nib 中取消归档时被调用。 viewDidLoad 在创建/取消归档 视图 时调用。当控制器的视图存储在单独的 nib 文件中时,这种区别尤其重要。

【讨论】:

ios 开发者小心behaviour on iOS is different awakeFromNib的规范中,“保证已经建立了它的所有出口和动作连接”,那么它是哪个出口?是观景台吗? 已创建和未归档有什么区别?未归档是指以非编程方式(即故事板和 xib)方式制作的文件吗?并创建是指纯程序化? 未归档意味着视图来自故事板/xib。 Created 意味着它是以编程方式实例化的。【参考方案2】:

同样重要的是awakeFromNib 函数在从内存警告中恢复后将永远不会被调用。但是,viewDidLoad 函数将被调用。

【讨论】:

2016年还有效吗? @khunshan 不,iOS 不再像以前那样自动卸载视图。【参考方案3】:

是的,没错。您不应该真的依赖 awakeFromNib 来完成此类任务。

awakeFromNib 类似于在 .NET 中反序列化后调用的事件。 viewDidLoad 类似于 .NET 中的 Load 事件。

如果您熟悉 .NET 中的概念,我认为这应该足够了。

【讨论】:

【参考方案4】:

我试着举个例子来回答:

如果定义customCell 类和customCell.xib 文件,然后使用- (NSArray *)loadNibNamed:(NSString *)name owner:(id)owner options:(NSDictionary *)options 加载单元格,则在解压缩xib 中的对象时调用awakeFromNib

如果你定义了customViewController,那么当customViewController 是使用- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 创建的。 viewDidLoad 将在加载到视图层次结构时被调用。

一些相关的混淆方法:

(void)loadView;如果子类不使用 nib,则应在此处创建自定义视图层次结构。如果您不指定 nib 名称,则 loadView 将尝试加载名称与视图控制器的类相同的 nib。如果不存在这样的 nib,那么您必须在调用 -view 之前调用 -setView:,或者覆盖 -loadView 方法以编程方式设置视图。 -loadView 永远不应该被直接调用。

(void)viewDidLoad:在视图加载后调用。对于在代码中创建的 viewController,这是在 -loadView 之后。对于从 nib 未归档的视图控制器,这是在设置视图之后。

【讨论】:

【参考方案5】:

对于 ViewController,IBOutlets 在 vi​​ewDidLoad() 中可用

这里stackView代表一个ViewController中的IBOutlet,stackView在awakeFromNib中是nil,但是在调用viewDidLoad()的时候已经实例化了。

【讨论】:

您缺少 super.awakeFromNib 和 super.viewDidLoad 调用。一旦 super.awakeFromNib 被调用,那么所有 Object 类型的 IBOutlets 将被启动,除了视图和 IBOutlets,它们是视图子视图的别名。

以上是关于我应该使用哪个,-awakeFromNib 还是 -viewDidLoad?的主要内容,如果未能解决你的问题,请参考以下文章

我应该在这里使用awakeFromNib还是initWithCoder?

我应该打电话给 [super awakeFromNib] 吗?

在 awakeFromNib 中访问视图?

OAuth/OpenID - 我应该使用哪个?

我应该为 JavaScript 链接使用哪个“href”值,“#”还是“javascript:void(0)”?

在 awakeFromNib 中添加子视图