我应该使用哪个,-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】:awakeFromNib
在 controller 本身从 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 在 viewDidLoad() 中可用
这里stackView代表一个ViewController中的IBOutlet,stackView在awakeFromNib中是nil,但是在调用viewDidLoad()的时候已经实例化了。
【讨论】:
您缺少 super.awakeFromNib 和 super.viewDidLoad 调用。一旦 super.awakeFromNib 被调用,那么所有 Object 类型的 IBOutlets 将被启动,除了视图和 IBOutlets,它们是视图子视图的别名。以上是关于我应该使用哪个,-awakeFromNib 还是 -viewDidLoad?的主要内容,如果未能解决你的问题,请参考以下文章
我应该在这里使用awakeFromNib还是initWithCoder?
我应该打电话给 [super awakeFromNib] 吗?