Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 无法将SKNode强制转换为SKNode的子类_Ios_Swift_Sprite Kit_Sknode - Fatal编程技术网

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
。My
returnNode()
只需获取名为的子节点,并将其返回给My
setupNode()
函数。我需要添加实体属性,因此我想将返回的
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
我在运行时遇到崩溃。我需要添加模块名,但这已修复。现在在其他目标上崩溃,因为模块名不匹配,但这是另一个问题。谢谢!