Ios 无法将SKNode强制转换为SKNode的子类
我正在从一个函数返回一个Ios 无法将SKNode强制转换为SKNode的子类,ios,swift,sprite-kit,sknode,Ios,Swift,Sprite Kit,Sknode,我正在从一个函数返回一个SKNode,我需要将它转换为一个自定义SKNode。我得到错误无法将SKNode的值分配给类型GroundNode。如果强制强制转换,它将编译,但在运行时失败。我错过了什么 // Custom node class class GroundNode: SKNode { weak var entity: GKEntity! } // Return node function func returnNode() -> SKNode {
SKNode
,我需要将它转换为一个自定义SKNode
。我得到错误无法将
SKNode的值分配给类型
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
。MyreturnNode()
只需获取名为的子节点,并将其返回给MysetupNode()
函数。我需要添加实体属性,因此我想将返回的SKNode
转换为GroundNode
类型
我在邮局见过斯塔克
这适用于SKSpiteNode
,但显然不适用于SKNode
,这对我来说没有多大意义
如果我将我的SKNode
从我的sks文件强制转换为GroundNode
,它会在运行时崩溃。我认为应该是这样
func returnNode()->GroundNode{
基于您的代码:
// 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设置自定义类:
首先
returnNode()
返回SKNode
类的实例。它还可能返回派生类的实例(例如GroundNode
),但调用站点从函数声明中不知道这一点。您正在尝试将此实例分配给SKNode
的子类-GroundNode
的变量,该变量在OOP中不合适
请参见OOP概念:
在面向对象编程语言中,超类的变量
类型可以包含子类实例
(可能,其他人可以更详细地解释这一点,但在我看来情况就是这样的)
第二
。当您怀疑某个类类型的变量可能包含派生类的实例时,可以进行类型转换以证明这一点
returnNode()
返回SKNode
或任何派生类的实例,但调用站点只希望处理派生类的实例(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)")
}
我可以问一下您为什么要执行此设置吗?当将常规SKNode分配给此GroundNode时,无论访问此变量的逻辑是什么,您都承诺它是GroundNode,即使它可能不是,因为returnNode可以返回任何SKNode对象。如果没有更多上下文,这对我来说听起来是个坏主意。您确定在
setupNode中
调用returnNode
实际上返回了一个GroundNode
实例?它似乎不是…使用调试器来观察实际发生的情况。我想你忘记设置自定义类了,我在回答中已经解释过。我试过了,但我从SKS文件中得到了一个SKNode。它无法将SKNode强制转换为GroundNode。如果我强制cast,它在运行时崩溃,而不是在编译时。这解决了崩溃问题,但会使我的节点为空,因为我将它分配给一个空的GroundNode。什么类型的实例func returnNode()
应该在运行时实际返回(GroundNode
或SKNode
)?您是否正在尝试从.sks
初始化GroundNode
?您是否可以解释一下您实际想要实现的目标?谢谢。谢谢您的回答。我已经更新了我的问题。returnNode返回一个SKNode。如果我在returnNode()中将我的SKNode强制转换为GroundNode
我在运行时遇到崩溃。我需要添加模块名,但这已修复。现在在其他目标上崩溃,因为模块名不匹配,但这是另一个问题。谢谢!