【问题标题】:Should I be using awakeFromNib or initWithCoder here?我应该在这里使用 awakeFromNib 还是 initWithCoder ?
【发布时间】: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;
}

【问题讨论】:

    标签: ios objective-c cocoa-touch


    【解决方案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 的原因。
    猜你喜欢
    • 1970-01-01
    • 2023-02-09
    • 2011-02-03
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多