删除节点会导致保留周期

Removing nodes causes retain cycles

在我的 scenekit 游戏中,节点是随机添加到场景中的。这些节点沿一个方向行进,直到它们经过所需的结束位置,然后它们将被删除。它们可以上下左右移动。 (我用的是node.runAction(SCNAction.repeatActionForever(SCNAction.moveBy(...

下面是我用来检测节点何时超过其结束位置以便将其删除的内容。

我遇到的问题是,虽然这可行,但出于某种原因,它导致了 SCNActionMoveSCNActionRepeat 的保留周期。

我发现避免这种情况的唯一方法是在游戏结束后在 for 循环中一次删除所有节点,但这并不理想,因为游戏可以玩很长时间。

谢谢!

func renderer(renderer: SCNSceneRenderer, updateAtTime time: NSTimeInterval) {

    // If any nodes have been spawned
    if spawnedNodeArray.count > 0 {

        // Get the first spawned node
        let node = rootNode.childNodeWithName(spawnedNodeArray[0].nodeName, recursively: true)!

        // If node is moving RIGHT, check if node has reached end position
        if spawnedNodeArray[0].Direction == "RIGHT" {
            // If node has reached past end position...
            if node.position.x >= Float(spawnedNodeArray[0].EndXPos) {
                node.removeAllActions()
                node.removeFromParentNode()
                spawnedNodeArray.removeAtIndex(0)
            }
        }

        // If node is moving LEFT, check if node has reached end position
        else if spawnedNodeArray[0].Direction == "LEFT" {
            // If node has reached past end position...
            if node.position.x <= Float(spawnedNodeArray[0].EndXPos) {
                node.removeAllActions()
                node.removeFromParentNode()
                spawnedNodeArray.removeAtIndex(0)
            }
        }

        // If node is moving DOWN, check if node has reached end position
        else if spawnedNodeArray[0].Direction == "DOWN" {
            // If node has reached past end position...
            if node.position.z >= Float(spawnedNodeArray[0].EndZPos) {
                node.removeAllActions()
                node.removeFromParentNode()
                spawnedNodeArray.removeAtIndex(0)
            }
        }

        // If node is moving UP, check if node has reached end position
        else if spawnedNodeArray[0].Direction == "UP" {
            // If node has reached past end position...
            if node.position.z <= Float(spawnedNodeArray[0].EndZPos) {
                node.removeAllActions()
                node.removeFromParentNode()
                spawnedNodeArray.removeAtIndex(0)
            }
        }
    }
}

不是您所问问题的直接答案,但是...

保留一个可重用节点池怎么样?不是在节点死亡时删除节点,而是将其 hidden 属性 设置为 true 并将其添加到重用队列中。不要总是创建一个新节点,而是首先尝试使现有节点出队。

我已经找到停止保留周期的方法了。

我必须给动作一个键,这样我就不会删除所有动作,而是只删除键的动作。

示例:

node.runAction(..., forKey: "moveAction") 

node.removeActionForKey("moveAction")