当我们可以在 awakeFromNib 中转储所有内容时,为啥还要使用 init(coder)?

Posted

技术标签:

【中文标题】当我们可以在 awakeFromNib 中转储所有内容时,为啥还要使用 init(coder)?【英文标题】:Why should we use init(coder) when we can just dump everything inside awakeFromNib?当我们可以在 awakeFromNib 中转储所有内容时,为什么还要使用 init(coder)? 【发布时间】:2017-03-30 17:20:20 【问题描述】:

我读过What exactly is init coder aDecoder?

但这并不能解释为什么不把所有东西都放在awakeFromNib 中而忘记使用init(coder aCoder : NSCoder)

在接受答案的 cmets 中,Fattie 说:

“有时你不能这样做”。您通常可以,但并非总是如此

谁能提供更多解释?

【问题讨论】:

请注意,如果您将其转储到 awakeFromNib 中,则在以编程方式添加时不会被调用 【参考方案1】:

如果您有需要在init 中初始化的lets,则必须使用它而不是awakeFromNib

这样做可以避免隐式解包选项。

编辑:

如果你想让你的类有属性,你可以这样做

 let a: String

 var a: String! = nil // this is called an "implicitly unwrapped optional" -- it's the ! at the end of the type that makes it that.

第一个更可取,因为它是安全的。在第二种情况下,您冒着在初始化之前访问a 的风险。

但是,为了确保a 始终被初始化,它需要在类的init 中获取其值。

所以,

init(coder aCoder : NSCoder) 
   a = "hello" // usually this is something more complex
   // read in coder or whatever else you need to do

如果你没有 init,那么你就不能有一个稍后会被初始化的 init。

【讨论】:

你的答案对我来说还是有点太密集了。能否详细说明或添加代码? 如果我错了,请纠正我。从Why optional constant does not automatically have a default value of nil 读取...我猜你的意思是如果我们 pass 初始化点,那么不变的属性将 setnil 并且不能再摆脱那种状态......基本上使该财产无用。 (我是在您进行编辑时写的) 解决该问题的方法是使其var 不是很好的属性实际上是一个常量,而您只是没有在初始化中对其进行初始化。如果它真的变化很大,一个 var(常规)可选就可以了(不是隐式展开) 感谢您的编辑。 1. 我之前的评论是否相关/正确? 2. var a: String! 不足以作为“隐式展开的可选”...我的意思是也将其设置为 nil 是的,没错。而且,是的,任何用 Type 声明的东西!是隐式展开的,我们希望避免这种情况。我们无法在 ViewController 的 IBOutlets 中避免它们(因为它们是在 viewDidLoad 中设置的,而不是 init)——您的问题与 VC 中的问题有关。如果有一个使用 NSCoder 的 init,那么我们可以在其中设置 outlet,并且不能用 ! 声明它们

以上是关于当我们可以在 awakeFromNib 中转储所有内容时,为啥还要使用 init(coder)?的主要内容,如果未能解决你的问题,请参考以下文章

当“awakeFromNib”运行时,UICollectionViewCell 内的动画不会运行。

目标 C:init 和 awakeFromNib

awakeFromNib() 在滚动开始时在 UICollectionViewCell 子类中调用了两次

awakeFromNib 中都有哪些网点?

处理作为文件所有者的对象的 awakeFromNib

awakeFromNib 返回 Null UILabel 值