SKAction runAction 不执行完成块
SKAction runAction does not execute completion block
A SKSpriteNode
是 SKNode
的子项,出于存储目的放置在 SKSpriteNode
的数组中。
这个SKSpriteNode
是用动画删除的。在此动画结束时,执行完成块以执行一些语句...
删除必须发生在 SKSpriteNode
父级和数组中。根据这 2 个删除的顺序,结果是否正确:
- 如果从 1/ 数组中删除
SKSpriteNode
,然后从 SKNode
父数组中删除 2/,则执行完成块。
- if inverse order, 1/
SKNode
parent's then 2/ the array, completion block不执行。
为什么会出现这种行为?
for position in listOfPositions {
theSprite:SKSpriteNode = theGrid[position]
/// the SKSpriteNode referenced by theSprite :
/// - belongs to an array of SKSpriteNode: theGrid
/// - belongs to a SKNode: theGameLayer
///
/// In other words this SKSpriteNode is referenced twice
///
let theActions = SKAction.sequence([
/// Some actions here
/// ...
/// Remove theSprite from the Grid
/// - position is an instance of a structure of my own
/// - theGrid is accessed via a subscript
///
SKAction.runBlock({self.theGrid[position] = nil}),
/// remove theSprite from it's parent
SKAction.removeFromParent(),
])
theSprite.runAction(theActions,completion:{NSLog("Deleted")})
}
显示完成消息。
现在如果removeFromParent
放在remove from theGrid
动作之前,如下,补全不执行:
let theActions = SKAction.sequence([
/// Some actions here
/// ...
/// remove theSprite from it's parent
SKAction.removeFromParent(),
/// remove theSprite from the Grid
SKAction.runBlock({self.theGrid[position] = nil}),
])
An SKAction object is an action that is executed by a node in the
scene (SKScene)...When the scene processes its nodes, actions associated with those
nodes are evaluated.
换句话说,当且仅当该节点在场景中时,该节点的动作是运行。通过调用 removeFromParent
,您从场景中移除节点,永远不会调用 runBlock
动作(因为节点不再在场景中),因此序列永远不会完成。由于序列未完成,因此不会调用完成块。
为了安全起见,我建议将 removeFromParent
调用移至完成块。这样的事情感觉更安全:
for position in listOfPositions {
let theSprite: SKSpriteNode = theGrid[position]
/// the SKSpriteNode referenced by theSprite :
/// - belongs to an array of SKSpriteNode: theGrid
/// - belongs to a SKNode: theGameLayer
///
/// In other words this SKSpriteNode is referenced twice
///
let theActions = SKAction.sequence([
/// Some actions here
/// ...
/// Remove theSprite from the Grid
/// - position is an instance of a structure of my own
/// - theGrid is accessed via a subscript
///
SKAction.runBlock({self.theGrid[position] = nil})
])
theSprite.runAction(theActions) {
/// remove theSprite from it's parent
/// Might need to weakly reference self here
theSprite.removeFromParent(),
NSLog("Deleted")
}
}
TL;DR
序列未完成,因此未调用序列的完成块。
A SKSpriteNode
是 SKNode
的子项,出于存储目的放置在 SKSpriteNode
的数组中。
这个SKSpriteNode
是用动画删除的。在此动画结束时,执行完成块以执行一些语句...
删除必须发生在 SKSpriteNode
父级和数组中。根据这 2 个删除的顺序,结果是否正确:
- 如果从 1/ 数组中删除
SKSpriteNode
,然后从SKNode
父数组中删除 2/,则执行完成块。 - if inverse order, 1/
SKNode
parent's then 2/ the array, completion block不执行。
为什么会出现这种行为?
for position in listOfPositions {
theSprite:SKSpriteNode = theGrid[position]
/// the SKSpriteNode referenced by theSprite :
/// - belongs to an array of SKSpriteNode: theGrid
/// - belongs to a SKNode: theGameLayer
///
/// In other words this SKSpriteNode is referenced twice
///
let theActions = SKAction.sequence([
/// Some actions here
/// ...
/// Remove theSprite from the Grid
/// - position is an instance of a structure of my own
/// - theGrid is accessed via a subscript
///
SKAction.runBlock({self.theGrid[position] = nil}),
/// remove theSprite from it's parent
SKAction.removeFromParent(),
])
theSprite.runAction(theActions,completion:{NSLog("Deleted")})
}
显示完成消息。
现在如果removeFromParent
放在remove from theGrid
动作之前,如下,补全不执行:
let theActions = SKAction.sequence([
/// Some actions here
/// ...
/// remove theSprite from it's parent
SKAction.removeFromParent(),
/// remove theSprite from the Grid
SKAction.runBlock({self.theGrid[position] = nil}),
])
An SKAction object is an action that is executed by a node in the scene (SKScene)...When the scene processes its nodes, actions associated with those nodes are evaluated.
换句话说,当且仅当该节点在场景中时,该节点的动作是运行。通过调用 removeFromParent
,您从场景中移除节点,永远不会调用 runBlock
动作(因为节点不再在场景中),因此序列永远不会完成。由于序列未完成,因此不会调用完成块。
为了安全起见,我建议将 removeFromParent
调用移至完成块。这样的事情感觉更安全:
for position in listOfPositions {
let theSprite: SKSpriteNode = theGrid[position]
/// the SKSpriteNode referenced by theSprite :
/// - belongs to an array of SKSpriteNode: theGrid
/// - belongs to a SKNode: theGameLayer
///
/// In other words this SKSpriteNode is referenced twice
///
let theActions = SKAction.sequence([
/// Some actions here
/// ...
/// Remove theSprite from the Grid
/// - position is an instance of a structure of my own
/// - theGrid is accessed via a subscript
///
SKAction.runBlock({self.theGrid[position] = nil})
])
theSprite.runAction(theActions) {
/// remove theSprite from it's parent
/// Might need to weakly reference self here
theSprite.removeFromParent(),
NSLog("Deleted")
}
}
TL;DR
序列未完成,因此未调用序列的完成块。