[英]In swift I cant initialize things before the super.init() or after
I want to be able to initialize the property subviewGroup using self but this gives me the error: Property 'self.gridView' not initialized at super.init call 我希望能够使用self初始化属性subviewGroup,但这给了我错误:在super.init调用中未初始化属性'self.gridView'
init(frame: NSRect) {
super.init(frame: frame)
subviewGroup = GridViewGroup(rows: 9, columns: 9, gridView: self)
}
/*** Properties ***/
let subviewGroup: GridViewGroup
Then if I put the super.init() after the initialization like this 然后如果我像这样在初始化后放置super.init()
init(frame: NSRect) {
subviewGroup = GridViewGroup(rows: 9, columns: 9, gridView: self)
super.init(frame: frame)
}
/*** Properties ***/
let subviewGroup: GridViewGroup
I get the error: 'self' used before super.init call 我收到错误:在super.init调用之前使用了'self'
I know I can use an Optional but since it will never be nil after the init() call it seems unnecessary. 我知道我可以使用Optional,但是由于init()调用后它永远不会为零,所以它似乎是不必要的。 Is there a way to do this properly without making subviewGroup an optional?
有没有一种方法可以正确地做到这一点而无需将subviewGroup设为可选?
Here is a working example using an optional 这是一个使用可选的工作示例
/*** Initializers ***/
init(frame: NSRect) {
super.init(frame: frame)
subviewGroup = GridViewGroup(rows: 9, columns: 9, gridView: self)
}
/*** Properties ***/
let subviewGroup: GridViewGroup?
This is exactly what implicitly unwrapped optionals are good for. 这正是隐式展开的可选对象所擅长的。 You can easily add them to your example like this:
您可以像这样轻松地将它们添加到您的示例中:
/*** Initializers ***/
init(frame: NSRect) {
super.init(frame: frame)
subviewGroup = GridViewGroup(rows: 9, columns: 9, gridView: self)
}
/*** Properties ***/
let subviewGroup: GridViewGroup!
Using an implicitly unwrapped optional allows you to treat the variable as if it weren't an optional and access the underlying directly when you call it. 使用隐式展开的可选变量可以使您将变量视为不是可选变量,并在调用它时直接访问基础。
Using a normal optional your code may look like var nonoptional: GridViewGroup = subviewGroup!
使用普通的可选代码可能看起来像
var nonoptional: GridViewGroup = subviewGroup!
while with implicitly unwrapped optionals you can discard the !: var nonoptional: GridViewGroup = subviewGroup
. 而使用隐式展开的可选对象,您可以放弃!:
var nonoptional: GridViewGroup = subviewGroup
。
From Apple's docs: 从苹果的文档:
Implicitly unwrapped optionals are useful when an optional's value is confirmed to exist immediately after the optional is first defined and can definitely be assumed to exist at every point thereafter.
当在第一个定义了可选对象的值之后立即确认该可选对象的值存在并且可以肯定地假定此后的每个点都存在时,隐式解开的可选对象很有用。 The primary use of implicitly unwrapped optionals in Swift is during class initialization
Swift中隐式展开的可选对象的主要用途是在类初始化期间
Your use case is crying out for an implicitly unwrapped optional; 您的用例正在寻求一个隐式展开的可选; this is a perfect example of when you would use one, and this pattern is used in many places throughout the Cocoa Touch API.
这是使用时机的完美示例,并且整个Cocoa Touch API的许多地方都使用了这种模式。
To begin with: 首先:
A. The proper order of your initialization should be something like this: 答:正确的初始化顺序应该是这样的:
init(frame: NSRect) {
subviewGroup = GridViewGroup(rows: 9, columns: 9, gridView: self)
super.init(frame: frame)
}
...per the Swift Programming Book: ...根据《 Swift编程手册》:
"A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a superclass initializer.” “指定的初始值设定项必须确保由其类引入的所有属性在委托给超类初始值设定项之前都已初始化。”
Then secondly: 然后第二:
B. Declare your subviewGroup
constant as an implicitly unwrapped optional; B.将您的
subviewGroup
常量声明为一个隐式展开的可选; doing so gives it a default value of nil
, meaning that as far as the compiler is concerned the requirement that it be initialized has been met! 这样做为它提供了默认值
nil
,这意味着就编译器而言,已满足对其初始化的要求! This form leaves you with a one-time opportunity (since it is a constant, where you used let
) to assign a non-nil value to it, which you can then do in your initializer without issue as so: 这种形式给您一次机会(因为它是一个常量,在其中使用
let
),可以为其分配一个非nil值,然后您就可以在初始化器中这样做,而不会出现问题:
let subviewGroup: GridViewGroup!
init(frame: NSRect) {
subviewGroup = GridViewGroup(rows: 9, columns: 9, gridView: self)
super.init(frame: frame)
}
I hope this helps! 我希望这有帮助!
The correct solution, as you found, is use optional. 如您所见,正确的解决方案是使用可选的。 But because you know it will never be
nil
outside init
, you can use implicitly unwrapped optional. 但是因为您知道它在
init
之外永远不会nil
,所以您可以使用隐式展开的optional。
let subviewGroup: GridViewGroup!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.