我应该在这里使用 awakeFromNib 还是 initWithCoder ?
Posted
技术标签:
【中文标题】我应该在这里使用 awakeFromNib 还是 initWithCoder ?【英文标题】:Should I be using awakeFromNib or initWithCoder here? 【发布时间】:2013-03-19 18:49:49 【问题描述】:我的初始视图控制器已加载,我需要一个 NSArray 来初始化,我应该在 awakeFromNib
方法还是 initWithCoder:
方法中处理这个问题? awakeFromNib 似乎工作得更好,因为我不需要返回任何东西,但它的工作原理是 nib 文件是以前使用的对吗?我不想使用很快就会崩溃的方法。
initWithCoder:
看起来像:
- (id)initWithCoder:(NSCoder *)decoder
if (self = [super initWithCoder:decoder])
self.articles = [[NSMutableArray alloc] init];
return self;
【问题讨论】:
【参考方案1】:-awakeFromNib
的意义在于,当您确定与 nib 中其他对象的所有连接都已建立时,您可以执行初始化操作。
nib 加载基础架构向每个 从 nib 存档重新创建的对象,但仅在所有对象之后 存档已加载并初始化。当一个对象收到 一个 awakeFromNib 消息,它保证有它的所有出口和 动作连接已经建立。
别忘了致电super
。
它不太可能很快消失,如果它使用了这么多代码,那么过渡期就会很长。是的,它的名字来自旧的“nib”文件格式,但this stack overflow question 清除了文件扩展名的差异。
因此,总而言之,当您为类设置内部实例变量时,任何一种方法都适用。请注意,在 init
方法(包括 -initWithCoder
)中,如果 setter 依赖于完全初始化的类(源 WWDC 2012 视频移至现代 Objective-c),则使用您的 setter 方法可能不安全。例如,设置一个引用 nib 文件中另一个对象的属性。
在UIViewController
子类中-initWithCoder
仅在从情节提要加载时调用。因为-awakeFromNib
被称为无论您是否使用故事板,使用它可能更有意义。
您可以考虑的另一种模式是lazy-getter:
- (NSMutableArray *)articles
if (_articles)
return _articles;
_articles = [[NSMutableArray alloc] init];
return _articles;
这种方法的好处是,如果您想对阵列进行进一步的设置,您可以在不再需要阵列时轻松丢弃阵列,而下次访问该属性时,您会再次获得一个新的。
【讨论】:
听起来不错,但在 UIViewControllers 上不会调用-initWithCoder:
。
我在从 Storyboard 实例化的 UIViewController 子类的 initWithCoder
方法中放置了一个断点,并且调试器命中了断点。 The docs 确认此行为。
从情节提要加载时,无论哪种方式,您都会得到-awakeFromNib
。
nib 加载系统使用 NSCoding 协议来“解冻”对象:结果调用 -initWithCoder;
@Honey 根据我自己的测试,与本文中指定的相反,如果您使用 init(nibNameOrNil: , nibBundleOrNil) 初始化程序(即不使用情节提要)。当然,在这种情况下,initWithCoder 也不会被调用,但这就是您不想仅仅依赖 awakeFromNib 的原因。以上是关于我应该在这里使用 awakeFromNib 还是 initWithCoder ?的主要内容,如果未能解决你的问题,请参考以下文章
我应该使用哪个,-awakeFromNib 还是 -viewDidLoad?