无法将SKNode强制转换为SKNode的子类

时间:2016-05-26 11:57:54

标签: ios swift sprite-kit sknode

我从一个函数返回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,它会在运行时崩溃。

3 个答案:

答案 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设置自定义类:

enter image description here

答案 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 {