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

Dou*_*ith 31 cocoa-touch objective-c ios

我的初始视图控制器已加载,我需要一个NSArray初始化,我应该在awakeFromNib方法或initWithCoder:方法中处理这个问题吗?awakeFromNib似乎工作得更好,因为我不需要返回任何内容,但它的工作原理是nib文件曾经被用过了吗?我不想使用即将破解的方法.

并会initWithCoder:只是看起来像:

- (id)initWithCoder:(NSCoder *)decoder {
    if (self = [super initWithCoder:decoder]) {
        self.articles = [[NSMutableArray alloc] init];
    }

    return self;
}
Run Code Online (Sandbox Code Playgroud)

jac*_*ash 45

关键-awakeFromNib在于,当您可以确定已建立与笔尖中其他对象的所有连接时,您可以执行初始化操作.

nib加载基础结构将awakeFromNib消息发送到从nib归档重新创建的每个对象,但只有在归档中的所有对象都已加载并初始化之后.当一个对象收到一个awakeFromNib消息时,它保证已经建立了所有的插座和动作连接.

别忘了打电话super.

它不太可能很快消失,如果它做了这么多代码使用它,过渡期将很长.是的,它的名字来自旧的"nib"文件格式,但是这个堆栈溢出问题清除了文件扩展名的差异.

因此总之,在为类设置内部实例变量时,任何一种方法都适合您.请注意,在内部init方法(包括-initWithCoder)中,使用setter方法可能不安全,因为setter依赖于完全初始化的类(源WWDC 2012视频移动到现代objective-c).一个例子是设置一个引用nib文件中另一个对象的属性.

UIViewController子类-initWithCoder中仅在从故事板加载时调用.随着-awakeFromNib被称为无论你用故事板与否,可能更有意义使用.

你可以考虑的另一个模式是懒惰的:

- (NSMutableArray *)articles{
    if (_articles){
        return _articles;
    }
    _articles = [[NSMutableArray alloc] init];
    return _articles;
}
Run Code Online (Sandbox Code Playgroud)

这种方法的好处是,如果您想对阵列进行进一步设置,您可以在不再需要时轻松丢弃阵列,下次访问该属性时,您将再次获得新阵列.

  • 我在UIViewController子类的`initWithCoder`方法中放置一个断点,该子类从Storyboard实例化,调试器命中断点.[文档](http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html#//apple_ref/doc/uid/TP40007457-CH10)确认此行为. (4认同)
  • @Honey根据我自己的测试,与本文中指定的相反,如果您使用 init(nibNameOrNil: , nibBundleOrNil) 初始化程序(即不使用故事板),则视图控制器上的 awakeFromNib 方法*不会*被调用。当然,在这种情况下, initWithCoder 也不会被调用,但这就是您不想仅仅依赖 awakeFromNib 的原因。 (2认同)