无法调用!=带有SKNode类型的参数列表?

时间:2014-12-02 15:37:08

标签: swift sprite-kit

我正在关注SpriteKit简介的教程,我收到了这个错误,在教程中,就像这样,但教程是在几个月前发布的,所以有些语法可能有改变。

错误出现在如果helloNode!= nil {...}

任何帮助?

谢谢!

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    var helloNode:SKNode = childNodeWithName("helloNode")!

//I get the error in the next line
    if helloNode != nil {
        helloNode.name = nil

        var moveUp:SKAction = SKAction.moveByX(0, y: 100, duration: 0.5)
        var zoom:SKAction = SKAction.scaleTo(2, duration: 0.25)
        var pause:SKAction = SKAction.waitForDuration(0.5)
        var fadeAway = SKAction.fadeOutWithDuration(0.25)
        var remove = SKAction.removeFromParent()
        var moveSequence = SKAction.sequence([moveUp, zoom, pause, fadeAway, remove])
        helloNode.runAction(moveSequence)
    }
}

3 个答案:

答案 0 :(得分:2)

在这一行:

var helloNode:SKNode = childNodeWithName("helloNode")!

childNodeWithName的返回值(可选)应用于强制解包运算符,其中:

    如果返回值为nil ,则
  • 抛出运行时异常 如果返回值不是nil
  • ,则
  • 评估为非可选SKNode

除此之外,helloNode被声明为非可选SKNode,非可选项永远不会为零。

要修复编译错误,请执行以下更改:

var helloNode: SKNode? = childNodeWithName("helloNode")

if let helloNode = helloNode {
    ...
}

通过这些更改,helloNode是可选的SKNode,可以包含nil或SKNode的实例。在下一个中使用了可选绑定:如果helloNode为nil,则let helloNode = helloNode计算结果为false,并跳过if语句中的代码。另一方面,如果helloNode不是nil,则它包含的值将被解包并分配给非可选变量(具有相同的名称,但您可以选择任何您想要的名称),其范围仅限于代码if语句的块。

答案 1 :(得分:1)

!末尾的childNodeWithName("helloNode")!表示该值不能为零,因此零检查无效。试试这个:

 if let temp = helloNode {
    // use temp instead of helloNode

    ...
}

或者将您的变量声明行更改为:

var helloNode:SKNode? = childNodeWithName("helloNode")

您可以在此处详细了解如何使用Optionals:Optionals in Swift

答案 2 :(得分:0)

这里已经有了不错的答案,但是它们(以及原始问题)涉及的代码并不像它可能的简洁或清晰。

  1. childNodeWithName的返回类型已经是可选的(SKNode?),因此在分配给您的本地helloNode变量时无需明确声明它。同样,类型推断使您无需为您正在创建的所有SKAction声明类型。

  2. 使用if let并使用与封闭范围相同的名称遮蔽本地绑定的非可选项并不是最可读的代码。

  3. 此外,如果您只分配给helloNode一次,并且仅在检查该分配后使用它,则只需将其绑定在一个范围内。说到只分配一次名称,就没有必要使用var来换取不会发生变化的事情。

  4. SKAction是可重复使用的。如果这种情况在游戏过程中不止一次发生,您可以考虑创建moveSequence一次(懒得偶然)并将其存放在一个属性中。

  5. 所以,改进版本:

    lazy var moveSequence: SKAction = {
        let moveUp = SKAction.moveByX(0, y: 100, duration: 0.5)
        let zoom = SKAction.scaleTo(2, duration: 0.25)
        let pause = SKAction.waitForDuration(0.5)
        let fadeAway = SKAction.fadeOutWithDuration(0.25)
        let remove = SKAction.removeFromParent()
        return SKAction.sequence([moveUp, zoom, pause, fadeAway, remove])
    }()
    
    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        if let helloNode == childNodeWithName("helloNode") {
            helloNode.name = nil
            helloNode.runAction(moveSequence)
        }
    }