Ios 当init()还初始化成员变量并引用时,将super.init()放在何处;“自我”;
我正在学习Swift,现在我有了以下代码:Ios 当init()还初始化成员变量并引用时,将super.init()放在何处;“自我”;,ios,swift,swift2,swift3,Ios,Swift,Swift2,Swift3,我正在学习Swift,现在我有了以下代码: import SpriteKit import GameplayKit class Player: GKEntity { var spriteComponent : SpriteComponent init(imageName: String) { super.init() // gives error: self.spriteComponent not initialized at super.init call let tex
import SpriteKit
import GameplayKit
class Player: GKEntity {
var spriteComponent : SpriteComponent
init(imageName: String) {
super.init() // gives error: self.spriteComponent not initialized at super.init call
let texture = SKTexture(imageNamed: imageName)
spriteComponent = SpriteComponent(entity: self, texture: texture, size: texture.size())
// super.init() Placing it here gives error on line above: "self used before super.init() call"
addComponent(spriteComponent)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
我已经看到了关于这一点的其他问题,但我无法想象我必须在SpriteComponent中创建一个虚拟初始值设定项(具有零args)并这样调用:
var spriteComponent = SpriteComponent()
为了在引用“self”之前调用super.init()
有人能解释我为什么要跳这种愚蠢的踢踏舞吗?一定有更好的方法做对了吧?斯威夫特不可能是那样的*&%&/(%对吗?所有非可选属性必须在创建对象之前进行初始化。将属性设置为可选属性。所有非可选属性必须在创建对象之前进行初始化。将属性设置为可选属性。
spriteComponent
是非可选变量。因此,必须在创建对象之前对其进行初始化调用super.init(解释第一个提到的错误)
稍后调用super.init
无法解决此问题,因为SpriteComponent
的构造函数需要对self的引用,而self只有在调用super.init
后才可用(解释第二个错误)
作为一种解决方案,您可以将spriteComponent
作为一个展开的可选组件:
var spriteComponent : SpriteComponent!
这指示编译器允许不初始化
spriteComponent
,并让您有责任在以后的时间点自己进行初始化。spriteComponent
是一个非可选变量。因此,必须在调用super.init
之前对其进行初始化(解释了第一个提到的错误)
稍后调用super.init
无法解决此问题,因为SpriteComponent
的构造函数需要对self的引用,而self只有在调用super.init
后才可用(解释第二个错误)
作为一种解决方案,您可以将spriteComponent
作为一个展开的可选组件:
var spriteComponent : SpriteComponent!
这指示编译器允许不初始化spriteComponent
,并让您有责任在以后的某个时间点自己进行初始化。这种“踢踏舞”是有原因的。
在swift中,类初始化分为两个阶段:
阶段#1-所有存储的属性都由定义它们的类给出一些初始值(nil也可以)
阶段#2-现在每个类都可以更改初始值并使用self
这是为什么?安全主要是——在第二阶段知道所有属性都有一些值
因此,在您的代码中,您可能不需要空的虚拟初始值设定项,但将您的sprite组件转换为可选组件可能很方便:
class Player: GKEntity{
var spriteComponent : SpriteComponent? = nil // optional
init(imageName: String)
{
super.init() // now OK
let texture = SKTexture(imageNamed: imageName)
spriteComponent = SpriteComponent(entity: self, texture: texture, size: texture.size())!
addComponent(spriteComponent!) // unwrap here
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
}这种“踢踏舞”是有原因的。
在swift中,类初始化分为两个阶段:
阶段#1-所有存储的属性都由定义它们的类给出一些初始值(nil也可以)
阶段#2-现在每个类都可以更改初始值并使用self
这是为什么?安全主要是——在第二阶段知道所有属性都有一些值
因此,在您的代码中,您可能不需要空的虚拟初始值设定项,但将您的sprite组件转换为可选组件可能很方便:
class Player: GKEntity{
var spriteComponent : SpriteComponent? = nil // optional
init(imageName: String)
{
super.init() // now OK
let texture = SKTexture(imageNamed: imageName)
spriteComponent = SpriteComponent(entity: self, texture: texture, size: texture.size())!
addComponent(spriteComponent!) // unwrap here
}
required init?(coder aDecoder: NSCoder)
{
fatalError("init(coder:) has not been implemented")
}
}在调用super.init()之前,必须初始化子类中声明的所有非可选属性 因此,您有两种解决此类问题的方法:
SpriteComponent?
或SpriteComponent!
)在调用super.init()之前,必须初始化子类中声明的所有非可选属性 因此,您有两种解决此类问题的方法:
SpriteComponent?
或SpriteComponent!
)尝试使用
var-spriteComponent:spriteComponent!
insteadOK,似乎有解决方案。来自Java/C等,我习惯于将变量初始化为null,如果没有其他指定的话。我可以自己将其初始化为nil。我仍然无法与Swift中的所有“and!”混淆。@PeterAnderson!and?n一旦掌握了窍门,旋转就非常简单,所以如果一个变量没有,这意味着它根本不能为零,所以基本上它不能有空值开始。!
意味着它可以为空开始,但一旦赋值,它就再也不能为零了(如果您试图在初始状态为零时访问它,应用程序将崩溃),?
基本上就像一个普通的java变量,但在访问它之前,您必须始终“展开”这基本上意味着在使用它之前确保它不为零,例如,如果让x=OptionalVariable或optionalVariabe?.someMethod()
(someMethod()
如果OptionalVariable
为零,则不会执行,这是一种简单的空检查,这是这个可选内容的重要部分)好的,谢谢解释。但是访问后来在init()
中构造的成员var node:EntityNode!
仍然会给我“可选类型'EntityNode'的值”未展开;。。。“
尝试使用var-spriteComponent:spriteComponent!
insteadOK似乎有解决方案。来自Java/C#etc的我被用于初始化为null的变量,如果没有另外指定。I