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

时间:2022-03-15 21:00:04

My initial view controller is loaded, and I need an NSArray to be init'd, should I take care of this in an awakeFromNib method or an initWithCoder: method? awakeFromNib seems to work nicer, as I don't need to return anything, but it works as nib files were what used to be used right? I don't want to use a method that will break soon.

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

And would initWithCoder: just look like:

并且initWithCoder:看起来像:

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

    return self;
}

1 个解决方案

#1


41  

The point of -awakeFromNib is so that you can do init stuff when you can be sure that all your connections to other objects in the nib have been established.

-awakeFromNib的要点是,当您可以确定已建立与nib中其他对象的所有连接时,您可以执行init。

The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive, but only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.

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

Dont forget to call super.

别忘了给超级打电话。

It is unlikely to go away any time soon, and if it did so much code uses it that the transition period would be long. Yes its name comes from the old "nib" file format but this stack overflow question clears up the differences in the file extensions.

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

So in summary either method will work for you as you are setting an internal instance variable for the class. Note that inside init methods (including -initWithCoder) it may not be safe to use your setter methods in case setters rely on the class being fully initialised (source WWDC 2012 video moving to modern objective-c). An example would be setting a property that references another object in the nib file.

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

In UIViewController subclasses -initWithCoder is only called when loading from a storyboard. As -awakeFromNib is called whether you use storyboards or not it might make more sense to use that.

在UIViewController子类中,只有在从故事板加载时才会调用-initWithCoder。无论你是否使用故事板,都会调用-awakeFromNib,使用它可能更有意义。

Another pattern you could consider is the lazy-getter:

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

-(NSMutableArray *)articles{
    if (_articles){
        return _articles;
    }
    _articles = [[NSMutableArray alloc] init];
    return _articles;
}

The benefit of this approach is that if you wanted to do further setup to the array you can easily discard the array when you don't need it anymore and the next time you access the property you have a fresh one again.

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

#1


41  

The point of -awakeFromNib is so that you can do init stuff when you can be sure that all your connections to other objects in the nib have been established.

-awakeFromNib的要点是,当您可以确定已建立与nib中其他对象的所有连接时,您可以执行init。

The nib-loading infrastructure sends an awakeFromNib message to each object recreated from a nib archive, but only after all the objects in the archive have been loaded and initialized. When an object receives an awakeFromNib message, it is guaranteed to have all its outlet and action connections already established.

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

Dont forget to call super.

别忘了给超级打电话。

It is unlikely to go away any time soon, and if it did so much code uses it that the transition period would be long. Yes its name comes from the old "nib" file format but this stack overflow question clears up the differences in the file extensions.

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

So in summary either method will work for you as you are setting an internal instance variable for the class. Note that inside init methods (including -initWithCoder) it may not be safe to use your setter methods in case setters rely on the class being fully initialised (source WWDC 2012 video moving to modern objective-c). An example would be setting a property that references another object in the nib file.

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

In UIViewController subclasses -initWithCoder is only called when loading from a storyboard. As -awakeFromNib is called whether you use storyboards or not it might make more sense to use that.

在UIViewController子类中,只有在从故事板加载时才会调用-initWithCoder。无论你是否使用故事板,都会调用-awakeFromNib,使用它可能更有意义。

Another pattern you could consider is the lazy-getter:

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

-(NSMutableArray *)articles{
    if (_articles){
        return _articles;
    }
    _articles = [[NSMutableArray alloc] init];
    return _articles;
}

The benefit of this approach is that if you wanted to do further setup to the array you can easily discard the array when you don't need it anymore and the next time you access the property you have a fresh one again.

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