Thanks for your reply.
It seems that the weakness of variables should be documented since it seems to be needed for setting up closures.
The following is the problem that I am having:
class GameScene:SKScene {
override func willMove(from view: SKView) {
...
do { // note this; is this overkill ???
func removeAllActionsForNode(_ node:SKNode) {
node.removeAllActions()
for childNode in node.children {
removeAllActionsForNode(childNode)
}
}
removeAllActionsForNode(self)
}
}
func doSomeAction() {
...
let moveToAction = SKAction.move(to: ..., duration: ...)
childNode.run(moveToAction) { [weak self, weak childNode] in
guard let childNode = childNode else { return }
self?.doSomeCompletion(childNode: childNode)
}
}
}
I want to insure that the deinit method of GameScene is called when I present a new scene even if actions are running. The code above seems to solve this problem, but I don't see why it really works. In other words, it seems like it is overkill.
First, consider the "willMove" segment of code. Do the actions for childNode get remove before completed? If not, then the current gameScene will be removed from the view and its update method will no longer be called and the actions with durations will not complete and it would then seem that the current gameScene will have retain cycles and won't be deleted. However, in my testing, it seems that the "willMove" segment of code will get rid of all the uncompleted actions and the current gameScene will deinit.
Second, consider the "doSomeAction" segment of code. It seems that "weak childNode" and the "guard" are not needed. This is why I asked my original question. It doesn't hurt to have "weak childNode", but I didn't understand why deinit would be called for the current gameScene if I left it out.