我从一个函数返回SKNode
,我需要将其转换为自定义SKNode
。我收到错误Cannot assign value of
SKNode to type
GroundNode。如果我强制转换,它会编译,但在运行时失败。我错过了什么?
// Custom node class
class GroundNode: SKNode {
weak var entity: GKEntity!
}
// Return node function
func returnNode() -> SKNode {
...
return node
}
// Where I am getting the error
func setupNode() {
var ground: GroundNode
ground = returnNode() // error here.
//// ground = returnNode() as! GroundNode fails at runtime.
}
编辑:我从sks文件中获得SKNode
。我的returnNode()
只是让孩子知名,并将其返回到我的setupNode()
函数。我需要添加实体属性,因此我想将返回的SKNode
转换为GroundNode
类型。
我看过this stackoverflow post。
这适用于SKSpiteNode
,但显然不适用于SKNode
,这对我没有多大意义。
如果我将我的SKNode
从我的sks文件转换为GroundNode
,它会在运行时崩溃。
答案 0 :(得分:1)
根据您的代码:
// Custom node class
class GroundNode: SKNode {
weak var entity: GKEntity! = GKEntity() // or some custom initialization...
}
// Where I am getting the error
func setupNode() {
var ground: GroundNode
ground = returnNode() as? GroundNode
}
这是因为returnNode输出是一个通用的SKNode,你必须明确你的转换为子类的GroundNode。
修改强>: 好的,有了您的更新,我想我已经理解了您的问题,您忘了为您的GroundNode设置自定义类:
答案 1 :(得分:1)
returnNode()
返回SKNode
类的实例。 可能也会返回派生类的实例(例如GroundNode
),但调用网站并不知道函数声明。您正尝试将此实例分配给SKNode
的子类 - GroundNode
的变量,该变量在OOP中不合适。
参见Dynamic Binding OOP概念:
在面向对象的编程语言中,是超类的变量 type可以包含子类实例。
(可能,其他人可以更详细地解释这一点,但事情看起来就像这样)
Type Casting。当你怀疑类类型的某个变量可能包含派生类的实例时,你可以进行类型转换以证明它。
returnNode()
返回SKNode
OR 任何派生类的实例,但调用网站只想处理派生类(GroundNode
)的实例,因此应使用其中一种铸造技术。
import GameplayKit
import SpriteKit
// Custom node class
class GroundNode: SKNode {
var entity: GKEntity = GKEntity()
}
// Return node function
func returnNode() -> SKNode {
// let's assume that you are correctly getting an instance
// of GroundNode class here, and return it from the function
// as of SKNode type
let returnNode: SKNode = GroundNode()
return returnNode
}
func setupNode() {
var groundNode: GroundNode?
// Type Casting
// Approach #1
let someNode = returnNode()
if someNode is GroundNode {
groundNode = someNode as! GroundNode
}
// Approach #2
groundNode = returnNode() as? GroundNode
print("groundNode = \(groundNode)")
}
答案 2 :(得分:0)
我认为应该是
func returnNode() -> GroundNode {