删除节点会导致保留周期
Removing nodes causes retain cycles
在我的 scenekit 游戏中,节点是随机添加到场景中的。这些节点沿一个方向行进,直到它们经过所需的结束位置,然后它们将被删除。它们可以上下左右移动。 (我用的是node.runAction(SCNAction.repeatActionForever(SCNAction.moveBy(...
)
下面是我用来检测节点何时超过其结束位置以便将其删除的内容。
我遇到的问题是,虽然这可行,但出于某种原因,它导致了 SCNActionMove 和 SCNActionRepeat 的保留周期。
我发现避免这种情况的唯一方法是在游戏结束后在 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")
在我的 scenekit 游戏中,节点是随机添加到场景中的。这些节点沿一个方向行进,直到它们经过所需的结束位置,然后它们将被删除。它们可以上下左右移动。 (我用的是node.runAction(SCNAction.repeatActionForever(SCNAction.moveBy(...
)
下面是我用来检测节点何时超过其结束位置以便将其删除的内容。
我遇到的问题是,虽然这可行,但出于某种原因,它导致了 SCNActionMove 和 SCNActionRepeat 的保留周期。
我发现避免这种情况的唯一方法是在游戏结束后在 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")